题目大意:
求S(n)的值 n<=1000000
这是官方题解给出的推导过程,orz,按这上面说的来写,就不难了
这里需要思考的就是G(n)这个如何利用积性函数的性质线性筛出来
作为一个质数,那么肯定G(i) = 2
1. 那么一个数 i 乘上了一个未出现的素数prime,那么就相当于,在当前符合的因子上面都乘了prime之后依旧符合,而原来 i 对应的数也符合,那么说明翻了两倍
也就是 g(i*prime) = 2*g(i) = g(prime) * g(i)
2. 如果这个乘上的素数prime已经存在于 i 中 , 那么仔细想一下,只有 i 那些符合的因子中已经带prime的必须再乘上这个prime,不然这个prime跑到 i/d中,gcd = prime了,其他的都不变,说明其实 g(i*prime) = g(i) 的
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 #define N 1000000 5 #define ll long long 6 const int MOD=258280327; 7 8 ll g[N+5] , t[N+5] , f[N+5]; 9 ll sum[N+5]; 10 int prime[N/5] , tot; 11 bool check[N+5]; 12 13 void get_g() 14 { 15 g[1] = 1; 16 for(int i=2 ; i<=N ; i++){ 17 if(!check[i]) prime[tot++] = i , g[i] = 2; 18 for(int j=0 ; j<tot ; j++){ 19 if((ll)prime[j]*i>N) break; 20 check[prime[j]*i] = true; 21 if(i%prime[j]) g[prime[j]*i] = g[prime[j]]*g[i]; 22 else {g[prime[j]*i]=g[i]; break;} 23 } 24 } 25 } 26 27 void get_t() 28 { 29 for(int k=2 ; k<=N ; k++) 30 for(int i=k ; i<=N ; i+=k) 31 t[i] = (t[i]+g[k-1])%MOD; 32 } 33 34 void get_f() 35 { 36 for(int i=1 ; i<=N ; i++) 37 f[i] = (f[i-1]+2*i-1-t[i-1])%MOD; 38 } 39 40 void init() 41 { 42 get_g(); 43 get_t(); 44 get_f(); 45 for(int i=1 ; i<=N ; i++) sum[i] = (sum[i-1]+f[i])%MOD; 46 } 47 48 int main() 49 { 50 //freopen("a.in" , "r" , stdin); 51 init(); 52 int T , n; 53 scanf("%d" , &T); 54 while(T--){ 55 scanf("%d" , &n); 56 printf("%I64d\n" , sum[n]); 57 } 58 return 0; 59 }
时间: 2024-11-15 23:01:16