...
51nod1239
给你一个n(n <= 1e10),求euler[1] + euler[2] + euler[3] + ... + euler[n]
用线性筛预处理一部分,然后递归,递归的时候用map存计算的结果会快很多
#include <iostream> #include <cstring> #include <cmath> #include <cstdio> #include <ctime> #include <map> using namespace std; #define rep(i, j, k) for(int i = int(j); i <= int(k); ++ i) typedef long long LL; map<LL, LL> mp; const LL MOD = 1e9 + 7; const int N = 1e7 + 5; bool isPrime[N]; int prime[N / 10], euler[N], primeNum = 0; int f[N]; inline void sieve() { memset(isPrime, 1, sizeof(isPrime)); euler[1] = 1; for (int i = 2; i < N; ++ i) { if (isPrime[i]) { prime[++ primeNum] = i; euler[i] = (i - 1); } for (int j = 1; j <= primeNum && i * prime[j] < N; ++ j) { isPrime[i * prime[j]] = 0; if (i % prime[j] == 0) { euler[i * prime[j]] = euler[i] * prime[j]; break; } else euler[i * prime[j]] = euler[i] * (prime[j] - 1); } } f[1] = 1; for (int i = 2; i < N; ++ i) f[i] = f[i - 1] + euler[i], f[i] %= MOD; } LL dfs(LL n) { if (n < N) return (LL)f[n]; if (mp.count(n)) return mp[n]; LL ret; if (n & 1) ret = n % MOD * ((n + 1) / 2 % MOD) % MOD; else ret = n / 2 % MOD * ((n + 1) % MOD) % MOD; int m = (int)sqrt(n + 0.5); for (int i = 2; i <= m; ++ i) { ret -= dfs(n / i); ret = (ret % MOD + MOD) % MOD; } for (int t = 1; t < n / m; ++ t) { ret -= dfs(t) * (n / t - n / (t + 1)); ret = (ret % MOD + MOD) % MOD; } return mp[n] = ret; } int main() { sieve(); // cout << 1.0 * clock() / CLOCKS_PER_SEC << endl; LL n; cin >> n; cout << dfs(n) << endl; }
1244
求一段区间内的莫比乌斯函数和。
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <map> using namespace std; typedef long long LL; #define rep(i, j, k) for (int i = int(j); i <= int(k); ++ i) const int N = 1e7 + 5; bool isPrime[N]; int prime[N / 10], mu[N], primeNum = 0; int f[N]; inline void sieve() { memset(isPrime, 1, sizeof(isPrime)); mu[1] = 1; rep(i, 2, N - 1) { if (isPrime[i]) { mu[i] = -1; prime[++ primeNum] = i; } rep(j, 1, primeNum) { if (i * prime[j] >= N) break; isPrime[i * prime[j]] = 0; if (i % prime[j] == 0) { mu[i * prime[j]] = 0; break; } else mu[i * prime[j]] = -mu[i]; } } rep(i, 1, N - 1) f[i] = f[i - 1] + mu[i]; } map<LL, int> mp; LL dfs(LL n) { if (n < N) return f[n]; if (mp.count(n)) return mp[n]; int ret = 1; int m = (int)sqrt(n + 0.5); rep(i, 2, m) { ret -= dfs(n / i); } rep(t, 1, n / m - 1) { ret -= dfs(t) * (n / t - n / (t + 1)); } return mp[n] = ret; } int main() { sieve(); LL a, b; cin >> a >> b; cout << dfs(b) - dfs(a - 1) << endl; }
51nod1237
for (int i =1; i <= n; ++i) for (int j = 1; j <= n; ++ j) ret = (ret + gcd(i, j)) %MOD,求ret
#include <iostream> #include <cstring> #include <map> #include <cmath> #include <cstdio> using namespace std; typedef long long LL; #define rep(i, j, k) for (int i = int(j); i <= int(k); ++ i) const int N = 1e7 + 5; const LL MOD = 1e9 + 7; bool isPrime[N]; int prime[N / 10], primeNum = 0, euler[N]; int f[N]; map<LL, LL> mp; inline void sieve() { memset(isPrime, 1, sizeof(isPrime)); euler[1] = 1; rep(i, 2, N - 1) { if (isPrime[i]) { prime[++ primeNum] = i; euler[i] = i - 1; } rep(j, 1, primeNum) { if (i * prime[j] >= N) break; isPrime[i * prime[j]] = 0; if (i % prime[j] == 0) { euler[i * prime[j]] = euler[i] * prime[j]; break; } else euler[i * prime[j]] = euler[i] * (prime[j] - 1); } } rep(i, 1, N - 1) f[i] = f[i - 1] + euler[i], f[i] %= MOD; } inline LL sqr(LL x) { x %= MOD; return x * x % MOD; } LL dfs(LL n) { if (n < N) return (LL)f[n]; if (mp.count(n)) return mp[n]; LL ret; if (n & 1) ret = n % MOD * ((n + 1) / 2 % MOD) % MOD; else ret = n / 2 % MOD * ((n + 1) % MOD) % MOD; int m = (int)sqrt(n + 0.5); for (int i = 2; i <= m; ++ i) { ret -= dfs(n / i); ret = (ret % MOD + MOD) % MOD; } for (int t = 1; t < n / m; ++ t) { ret -= dfs(t) * (n / t - n / (t + 1)); ret = (ret % MOD + MOD) % MOD; } return mp[n] = ret; } int main() { sieve(); LL n, ret = 0; cin >> n; int m = (int)sqrt(n + 0.5); rep(i, 1, m) { ret += euler[i] * sqr(n / i) % MOD; ret %= MOD; } rep(t, 1, n / m - 1) { LL tmp = dfs(n / t) - dfs(n / (t + 1)); tmp = (tmp % MOD + MOD) % MOD; ret += sqr(t) * tmp % MOD; ret %= MOD; } cout << ret << endl; }
51nod1238
for (int i = 1; i <= n; ++ i) for (int j = 1; j <= n; ++j) ans += LCM(i, j);
#include <iostream> #include <cstdio> #include <cstring> #include <map> #include <cmath> using namespace std; typedef long long LL; #define rep(i, j, k) for (int i = int(j); i <= int(k); ++ i) const LL MOD = 1e9 + 7; const int N = 1e7 + 5; bool isPrime[N]; int prime[N / 10], primeNum = 0, euler[N]; LL f[N]; LL inv2, inv3; inline LL qpow(LL a, LL b) { a %= MOD; LL c = 1; while (b) { if (b & 1) c = c * a % MOD; a = a * a % MOD; b >>= 1; } return c; } inline LL sqr(LL x) { x %= MOD; return x * x % MOD; } inline LL soo(LL x) { x %= MOD; return x * (x + 1) % MOD * inv2 % MOD; } inline LL sob(LL x) { x %= MOD; return sqr(x * (x + 1) % MOD * inv2 % MOD); } inline LL sos(LL x) { x %= MOD; return x * (x + 1) % MOD * (2 * x + 1) % MOD * inv2 % MOD * inv3 % MOD; } inline void sieve() { memset(isPrime, 1, sizeof(isPrime)); euler[1] = 1; rep(i, 2, N - 1) { if (isPrime[i]) { prime[++ primeNum] = i; euler[i] = i - 1; } rep(j, 1, primeNum) { if (i * prime[j] >= N) break; isPrime[i * prime[j]] = 0; if (i % prime[j] == 0) { euler[i * prime[j]] = euler[i] * prime[j]; break; } else euler[i * prime[j]] = euler[i] * (prime[j] - 1); } } rep(i, 1, N - 1) f[i] = f[i - 1] + sqr(i) * euler[i] % MOD, f[i] %= MOD; } map<LL, LL> mp; LL dfs(LL x) { if (x < N) return f[x]; if (mp.count(x)) return mp[x]; LL ret = sob(x); int m = (int)sqrt(x + 0.5); rep(i, 2, m) { ret -= sqr(i) * dfs(x / i); ret = (ret % MOD + MOD) % MOD; } rep(t, 1, x / m - 1) { LL tmp = sos(x / t) - sos(x / (t + 1)); tmp = (tmp % MOD + MOD) % MOD; ret -= tmp * dfs(t); ret = (ret % MOD + MOD) % MOD; } return mp[x] = ret; } int main() { inv2 = qpow(2, MOD - 2); inv3 = qpow(3, MOD - 2); sieve(); LL n; cin >> n; LL ans = 0; int m = sqrt(n + 0.5); rep(i, 1, m) { ans += i * dfs(n / i) % MOD; ans %= MOD; } rep(t, 1, n / m - 1) { LL tmp = soo(n / t) - soo(n / (t + 1)); tmp = (tmp % MOD + MOD) % MOD; ans += tmp * dfs(t) % MOD; ans %= MOD; } cout << ans << endl; }