3944: Sum
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 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
#include<bits/stdc++.h>
#define rint register int
#define ll long long
#define N 2000001
using namespace std;
int pri[N>>],vis[N],cnt,cas,n;
ll phi[N],mo[N],p[N],q[N];
void predeal(){
mo[]=phi[]=;
for(rint i=;i<N;++i){
if(!vis[i]){phi[i]=i-;mo[i]=-;pri[++cnt]=i;}
for(rint j=;j<=cnt&&pri[j]*i<N;++j){
vis[i*pri[j]]=;
if(i%pri[j]){phi[i*pri[j]]=phi[i]*(pri[j]-);mo[i*pri[j]]=-mo[i];}
else{phi[i*pri[j]]=phi[i]*pri[j];mo[i*pri[j]]=;break;}
}
}
for(rint i=;i<N;++i)phi[i]+=phi[i-],mo[i]+=mo[i-];
}
ll getp(int x){return x<N?phi[x]:p[n/x];}
ll getq(int x){return x<N?mo[x]:q[n/x];}
void solve(int x){
if(x<N)return;int i,j=,t=n/x;
if(vis[t])return;vis[t]=;
p[t]=(1ll*x+)*x/;q[t]=;
while(j<x){
i=j+;j=x/(x/i);solve(x/i);
p[t]-=getp(x/i)*(j-i+);
q[t]-=getq(x/i)*(j-i+);
}
}
int main(){
scanf("%d",&cas);predeal();
while(cas--){
scanf("%d",&n);memset(vis,,sizeof(vis));
if(n<N)printf("%lld %lld\n",phi[n],mo[n]);
else{solve(n);printf("%lld %lld\n",p[],q[]);}
}
return ;
}