您的位置:首页 > 其它

BZOJ_P3944 Sum(数论+杜教筛)

2016-03-25 20:52 357 查看
BZOJ传送门

Time Limit: 10 Sec Memory Limit: 128 MB

Submit: 1108 Solved: 270

[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

HINT

Source

跟前面两道题一样!

循环变量要开long long !!!!!!!!!

long long/(long long/int)会计算错误!!!!

你在逗我!!!!!!

下面那个是拿哈希表写的

#include<cstdio>
#include<cstring>
#define N 2000000
#define M 100005
inline long long in(long long x=0,char ch=getchar()){while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x;}
int cnt,t;int pr[N+10],mu[N+10];long long phi[N+10];long long n;
long long p[M];int q[M];bool v[M];
void Pre(){
mu[1]=phi[1]=1;
for(int i=2;i<=N;i++){
if(!phi[i]) pr[++cnt]=i,mu[i]=-1,phi[i]=i-1;
for(int j=1;j<=cnt&&i*pr[j]<=N;j++){
if(!(i%pr[j])){phi[i*pr[j]]=phi[i]*pr[j];break;}
mu[i*pr[j]]=-mu[i];phi[i*pr[j]]=phi[i]*(pr[j]-1);
}
}
for(int i=2;i<=N;i++) mu[i]+=mu[i-1],phi[i]+=phi[i-1];
}
inline long long getphi(int x){return x<=N?phi[x]:p[n/x];}
inline int getmu(int x){return x<=N?mu[x]:q[n/x];}
inline void calc(long long x){
if(x<=N) return;long long t=n/x;
if(v[t]) return;v[t]=1;
p[t]=(x*(x+1))>>1;q[t]=1;
for(long long i=2,j;i<=x;i=j+1){
j=x/(x/i);calc(x/i);
p[t]-=getphi(x/i)*(j-i+1);q[t]-=getmu(x/i)*(j-i+1);
}
}
int main(){
Pre();t=in();
while(t--){
memset(v,0,sizeof(v));n=in();
if(n<=N) printf("%lld ",phi
),printf("%d\n",mu
);
else calc(n),printf("%lld ",p[1]),printf("%d\n",q[1]);
}
return 0;
}


#include<cstdio>
#include<cstring>
#define N 1000000
#define Mod 2333333
inline int in(int x=0,char ch=getchar()){while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x;}
int cnt,t,sum;int pr[N+10],mu[N+10];long long phi[N+10];long long n;
struct ANS{
int a;long long b;
ANS operator - (const ANS &x)const {return (ANS){a-x.a,b-x.b};}
ANS operator * (const int x)const {return (ANS){a*x,b*x};}
}ans;
struct map{long long k,nxt;ANS v;}hash[Mod];int head[Mod];
void Pre(){
mu[1]=phi[1]=1;
for(int i=2;i<=N;i++){
if(!phi[i]) pr[++cnt]=i,mu[i]=-1,phi[i]=i-1;
for(int j=1;j<=cnt&&i*pr[j]<=N;j++){
if(!(i%pr[j])){phi[i*pr[j]]=phi[i]*pr[j];break;}
mu[i*pr[j]]=-mu[i];phi[i*pr[j]]=phi[i]*(pr[j]-1);
}
}
for(int i=2;i<=N;i++) mu[i]+=mu[i-1],phi[i]+=phi[i-1];
}
inline void add(long long k,ANS a){
int ha=k%Mod;hash[++sum].k=k,hash[sum].v=a,hash[sum].nxt=head[ha],head[ha]=sum;
}
inline ANS calc(long long x){
if(x<=N) return (ANS){mu[x],phi[x]};int ha=x%Mod;
for(int i=head[ha];i;i=hash[i].nxt) if(hash[i].k==x) return hash[i].v;
ANS res;res.a=1,res.b=(x*(x+1))>>1;
for(long long i=2,j;i<=x;i=j+1){
j=x/(x/i);res=res-calc(x/i)*(j-i+1);
}
add(x,res);return res;
}
int main(){
Pre();t=in();
while(t--){
n=in();ans=calc(n);
printf("%lld ",ans.b);printf("%d\n",ans.a);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: