3944: Sum
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5149 Solved: 1385
[Submit][Status][Discuss]
Description
Input
一共T+1行
第1行为数据组数T(T<=10)
第2~T+1行每行一个非负整数N,代表一组询问
Output
一共T行,每行两个用空格分隔的数ans1,ans2
Sample Input
6
1
2
8
13
30
2333
1
2
8
13
30
2333
Sample Output
1 1
2 0
22 -2
58 -3
278 -3
1655470 2
2 0
22 -2
58 -3
278 -3
1655470 2
杜教筛入门?
http://blog.csdn.net/popoqqq/article/details/45023331
1 #include<bits/stdc++.h> 2 #define rint register int 3 #define ll long long 4 #define N 2000001 5 using namespace std; 6 int pri[N>>1],vis[N],cnt,cas,n; 7 ll phi[N],mo[N],p[N],q[N]; 8 void predeal(){ 9 mo[1]=phi[1]=1; 10 for(rint i=2;i<N;++i){ 11 if(!vis[i]){phi[i]=i-1;mo[i]=-1;pri[++cnt]=i;} 12 for(rint j=1;j<=cnt&&pri[j]*i<N;++j){ 13 vis[i*pri[j]]=1; 14 if(i%pri[j]){phi[i*pri[j]]=phi[i]*(pri[j]-1);mo[i*pri[j]]=-mo[i];} 15 else{phi[i*pri[j]]=phi[i]*pri[j];mo[i*pri[j]]=0;break;} 16 } 17 } 18 for(rint i=1;i<N;++i)phi[i]+=phi[i-1],mo[i]+=mo[i-1]; 19 } 20 ll getp(int x){return x<N?phi[x]:p[n/x];} 21 ll getq(int x){return x<N?mo[x]:q[n/x];} 22 void solve(int x){ 23 if(x<N)return;int i,j=1,t=n/x; 24 if(vis[t])return;vis[t]=1; 25 p[t]=(1ll*x+1)*x/2;q[t]=1; 26 while(j<x){ 27 i=j+1;j=x/(x/i);solve(x/i); 28 p[t]-=getp(x/i)*(j-i+1); 29 q[t]-=getq(x/i)*(j-i+1); 30 } 31 } 32 int main(){ 33 scanf("%d",&cas);predeal(); 34 while(cas--){ 35 scanf("%d",&n);memset(vis,0,sizeof(vis)); 36 if(n<N)printf("%lld %lld\n",phi[n],mo[n]); 37 else{solve(n);printf("%lld %lld\n",p[1],q[1]);} 38 } 39 return 0; 40 }