https://ac.nowcoder.com/acm/contest/8051
C - 有用的 LCM
题意:定义前缀 lcm 为 Ln=lcm(1,2,3,...,n) ,且一个数 x 对其前缀 lcm 有贡献当且仅当 Lx−1=Lx 。特别的, 1 不视为对其前缀 lcm 有贡献。现在你需要求出 1~ n 内所有对其前缀 lcm 有贡献的数的个数。
min25筛
显然答案是 p 的幂次的个数。
只有小于等于 n 的质数有大于 1 的幂次,对于这些质数欧拉筛出来,同时统计幂次的个数。
还需要得到小于等于 n 的质数的个数,min25筛模板题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| #include <bits/stdc++.h> #define debug(x) cout << #x << ":\t" << (x) << endl; using namespace std; #define ll long long const int N = 2e6 + 10; const int INF = 0x3f3f3f3f; const ll inf = 0x3f3f3f3f3f3f3f3f; ll n, ans; int vis[N], prime[N], cnt, sqr; ll sieve(int m) { ll res = 0; for (int i = 2; i <= m; i++) { if (!vis[i]) { prime[++cnt] = i; ll x = n; while (x >= i) { x /= i; res++; } res--; } ll d; for (int j = 1; j <= cnt && (d = 1ll*i * prime[j]) <= m; j++) { vis[d] = 1; if (i%prime[j] == 0)break; } } return res; } ll w[N]; int m; ll g[N]; int id[2][N]; int main() { scanf("%lld", &n); sqr = (int)sqrt(n); ans = sieve(sqr); for (ll i = 1, j; i <= n; i = j + 1) { j = n / (n / i); w[++m] = n / i; if (w[m] <= sqr)id[0][w[m]] = m; else id[1][n / w[m]] = m; g[m] = w[m] - 1; } for (int j = 1; j <= cnt; j++) { for (int i = 1; i <= m && w[i] >= 1ll*prime[j] * prime[j]; i++) { int k = (w[i] / prime[j] <= sqr ? id[0][w[i] / prime[j]] : id[1][n / (w[i] / prime[j])]); ll tmp = g[k] - j + 1; g[i] -= tmp; } } printf("%lld\n", g[1] + ans); return 0; }
|
斐波那契?数列!
题意:题目分为两小部分。 第一个部分中你需要求出:对于递推数列 ai=x⋅ai−1+y⋅ai−2+z⋅ai−3 的前缀平方和 ∑i=1nai2 ;第二个部分你需要回答 q 个询问:对于每个询问值 x 你需要回答:斐波那契数列 fi 的前缀平方和 Fx 的值。
第一部分,矩阵快速幂直接求即可。
第二部分,有结论 ∑i=1nfi2=fi⋅fi+1。
需要快速求出 fi,但是由于 5 在模 998244353 下没有二次剩余,所有不能套公式。
但是又有结论
(fn+1fnfnfn−1)=(1110)n(f2n+1f2nf2nf2n−1)=(1110)2n⇓(f2n+1f2nf2nf2n−1)=(fn+1fnfnfn−1)2
所以可以 O(logx) 求出 fx,fx+1。
注意 n 要用 __int128.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| #include <bits/stdc++.h> #define debug(x) cout << #x << ":\t" << (x) << endl; using namespace std; #define ll long long const int N = 2e6 + 10; const int INF = 0x3f3f3f3f; const ll inf = 0x3f3f3f3f3f3f3f3f; const ll mod = 998244353; inline __int128 read() { __int128 x = 0, f = 1; char ch = getchar(); while (ch<'0' || ch>'9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; }
inline void write(__int128 x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x / 10); putchar(x % 10 + '0'); }
__int128 n; ll a1, a2, a3, x, y, z; int q; struct Mat { ll a[10][10]; int r, c; Mat(int _r, int _c) { r = _r, c = _c, memset(a, 0, sizeof(a)); } }; Mat operator*(Mat X, Mat Y) { Mat Z(X.r, Y.c); for (int i = 0; i < X.r; i++) { for (int j = 0; j < Y.c; j++) { for (int k = 0; k < X.c; k++) { Z.a[i][j] = (Z.a[i][j] + 1ll * X.a[i][k] * Y.a[k][j] % mod) % mod; } } } return Z; } Mat pow(Mat a, __int128 n) { Mat res(a.r, a.c); for (int i = 0; i < a.r; i++) res.a[i][i] = 1; while (n > 0) { if (n % 2 != 0)res = res * a; a = a * a; n /= 2; } return res; } Mat A(7, 1), B(7, 7); typedef pair<int, int>pii; pii fib(int n) { if (n == 0) return { 0, 1 }; pii p = fib(n >> 1); if (n & 1) { int a = (1ll * p.first*p.first%mod + 1ll * p.second*p.second%mod) % mod; int b = 1ll * p.second*(2ll * p.first%mod + p.second) % mod; return { a,b }; } else { int a = 1ll * p.first*(2ll * p.second%mod - p.first + mod) % mod; int b = (1ll * p.first*p.first%mod + 1ll * p.second*p.second%mod) % mod; return { a,b }; } } int main() { n = read(); scanf("%lld%lld%lld%lld%lld%lld", &a1, &a2, &a3, &x, &y, &z); A.a[0][0] = (a1 * a1 + a2 * a2 + a3 * a3) % mod; A.a[1][0] = a3 * a3%mod; A.a[2][0] = a2 * a2%mod; A.a[3][0] = a1 * a1%mod; A.a[4][0] = a3 * a2%mod; A.a[5][0] = a3 * a1%mod; A.a[6][0] = a2 * a1%mod; for (int i = 0; i < 2; i++) { B.a[i][1] = x * x%mod; B.a[i][2] = y * y%mod; B.a[i][3] = z * z%mod; B.a[i][4] = 2 * x*y%mod; B.a[i][5] = 2 * x*z%mod; B.a[i][6] = 2 * y*z%mod; } B.a[0][0] = 1; B.a[1][0] = 0; B.a[2][1] = B.a[3][2] = B.a[6][4] = 1; B.a[4][1] = x; B.a[4][4] = y; B.a[4][5] = z; B.a[5][2] = y; B.a[5][4] = x; B.a[5][6] = z; if (n == 1)printf("%lld\n", a1*a1%mod); else if (n == 2)printf("%lld\n", (a1*a1 + a2 * a2) % mod); else { A = pow(B, n - 3)*A; printf("%lld\n", A.a[0][0]); } scanf("%d", &q); while (q--) { int i; scanf("%d", &i); auto p = fib(i); int ans = 1ll * p.first * p.second % mod; printf("%d\n", ans); } return 0; }
|