[BZOJ 4916]神犇和蒟蒻
Description
Input
Output
Sample Input
Sample Output
1
题解
首先注意到 $A$ 直接输出 $1$ 得满分。因为只有 $\mu(1^2)=1$ 。至于为什么,想想莫比乌斯函数是什么。
对于第二问容易发现 $\varphi(i^2)=i\cdot\varphi(i)$ 。至于为什么,想想你是怎么线性筛欧拉函数的。
对于函数 $f(i)=i\cdot\varphi(i)$ 容易发现,这也是个积性函数。我们可以将阈值内的线性筛筛出来。对于阈值外的,考虑杜教筛。
求 $S(n)=\sum\limits_{i=1}^nf(i)$
上述式子 $$g(1)S(n)=\sum_{i=1}^n(g*f)(i)-\sum_{i=2}^ng(i)S\left(\left\lfloor\frac{n}{i}\right\rfloor\right)$$
考虑到 $\sum\limits_{d\mid n}\varphi(d)=n$ ,又由于 $(g*f)(n)=\sum\limits_{d\mid n}\varphi(d)d\cdot g\left(\frac{n}{d}\right)$ 。我们考虑让 $g(n)=id(n)$ ,那么 $(id*f)(n)=\sum\limits_{d\mid n}n\cdot\varphi(d)=n^2$ 。由于 $\sum\limits_{i=1}^ni^2=\frac{n(n+1)(2n+1)}{6}$ 。显然这个卷积的前缀为 $\sum\limits_{i=1}^n(g*f)(i)=\frac{n(n+1)(2n+1)}{6}$ 。
故对于 $f$ $$S(n)=\frac{n(n+1)(2n+1)}{6}-\sum_{i=2}^ni\cdot S\left(\left\lfloor\frac{n}{i}\right\rfloor\right)$$
1 //It is made by Awson on 2018.1.24 2 #include <set> 3 #include <map> 4 #include <cmath> 5 #include <ctime> 6 #include <queue> 7 #include <stack> 8 #include <cstdio> 9 #include <string> 10 #include <vector> 11 #include <cstdlib> 12 #include <cstring> 13 #include <iostream> 14 #include <algorithm> 15 #define LL long long 16 #define Abs(a) ((a) < 0 ? (-(a)) : (a)) 17 #define Max(a, b) ((a) > (b) ? (a) : (b)) 18 #define Min(a, b) ((a) < (b) ? (a) : (b)) 19 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b)) 20 #define writeln(x) (write(x), putchar('\n')) 21 #define lowbit(x) ((x)&(-(x))) 22 using namespace std; 23 const int MOD = 1e9+7; 24 const int N = 2333333; 25 void read(int &x) { 26 char ch; bool flag = 0; 27 for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar()); 28 for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar()); 29 x *= 1-2*flag; 30 } 31 void write(int x) { 32 if (x > 9) write(x/10); 33 putchar(x%10+48); 34 } 35 36 int n, inv2, inv6, f[N+5]; 37 int prime[N+5], isprime[N+5], tot; 38 map<int, int>mp; 39 40 int quick_pow(int a, int b) { 41 int ans = 1; 42 while (b) { 43 if (b&1) ans = 1ll*ans*a%MOD; 44 a = 1ll*a*a%MOD, b >>= 1; 45 } 46 return ans; 47 } 48 void get_f() { 49 memset(isprime, 1, sizeof(isprime)); isprime[1] = 0, f[1] = 1; 50 for (int i = 2; i <= N; i++) { 51 if (isprime[i]) prime[++tot] = i, f[i] = 1ll*i*(i-1)%MOD; 52 for (int j = 1; j <= tot && i*prime[j] <= N; j++) { 53 isprime[i*prime[j]] = 0; 54 if (i%prime[j]) f[i*prime[j]] = 1ll*f[i]*(prime[j]-1)%MOD*prime[j]%MOD; 55 else {f[i*prime[j]] = 1ll*f[i]*prime[j]%MOD*prime[j]%MOD; break; } 56 } 57 (f[i] += f[i-1]) %= MOD; 58 } 59 } 60 int cal(int x) { 61 if (x <= N) return f[x]; 62 if (mp.count(x)) return mp[x]; 63 int ans = 1ll*x*(x+1)%MOD*(2*x+1)%MOD*inv6%MOD; 64 for (int i = 2, last; i <= x; i = last+1) { 65 last = x/(x/i); (ans -= 1ll*(last+i)*(last-i+1)%MOD*inv2%MOD*cal(x/i)%MOD) %= MOD; 66 } 67 return mp[x] = ans; 68 } 69 void work() { 70 get_f(); inv2 = quick_pow(2, MOD-2), inv6 = quick_pow(6, MOD-2); read(n); 71 writeln(1); writeln((cal(n)+MOD)%MOD); 72 } 73 int main() { 74 work(); 75 return 0; 76 }