bzoj3944Sum

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

Sample Output

1 1
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
",phi[n],mo[n]);
37         else{solve(n);printf("%lld %lld
",p[1],q[1]);}
38     }
39     return 0;
40 }
 
原文地址:https://www.cnblogs.com/wsy01/p/8324722.html