2012 2012 ACM/ICPC Asia Regional Jinhua Online Sum
http://acm.hdu.edu.cn/showproblem.php?pid=4407
思路:问题转化:给定n,p,求n内和p互质的数的和。
剩下的暴力。
关键代码是队友写的:
View Code
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<map> #include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> using namespace std; map<int,int>as; map<int,int>::iterator ps; __int64 n,m,ans; __int64 cnt1[10000],cnt2[10000]; __int64 zs[1000]; __int64 t1; __int64 gcd(__int64 x,__int64 y){return y?gcd(y,x%y):x;} bool cmp(__int64 a,__int64 b) { return abs(a)<abs(b);} void chushi() { zs[0]=2; __int64 i,j,len=1; for(i=3;i<=1000;i+=2) { for(j=0;zs[j]*zs[j]<i;j++) if(i%zs[j]==0) break; if(zs[j]*zs[j]>=i) zs[len++]=i; } } void fc(__int64 i,__int64 j,__int64 s) { if(i==j) { cnt2[t1++]=s; return ; } fc(i+1,j,s); fc(i+1,j,s*cnt1[i]); } __int64 Sum(__int64 a,__int64 b,__int64 p) { __int64 i,t,k; if(p==1) { return (a+b)*(b-a+1)/2; } t=0; for(i=0;zs[i]*zs[i]<=p;i++) if(p%zs[i]==0){ cnt1[t++]=-zs[i]; while(p%zs[i]==0) p/=zs[i]; } if(p>1) cnt1[t++]=-p; t1=0; fc(0,t,1); sort(cnt2,cnt2+t1,cmp); cnt2[t1]=b+1; a--; __int64 aa=0,bb=0; for(i=0;abs(cnt2[i])<=a;i++) { k=a/abs(cnt2[i]); aa+=k*(k+1)/2*cnt2[i]; } for(i=0;abs(cnt2[i])<=b;i++) { k=b/abs(cnt2[i]); bb+=k*(k+1)/2*cnt2[i]; } return bb-aa; } int main() { __int64 t,i,l,r,p,c; chushi(); scanf("%I64d",&t); while(t--){ scanf("%I64d%I64d",&n,&m); as.clear(); while(m--){ scanf("%I64d",&i); if(i==1){ scanf("%I64d %I64d %I64d",&l,&r,&p); ans = Sum(l,r,p); for(ps=as.begin(); ps!=as.end(); ps++) if(ps->first>=l && ps->first<=r){ if(gcd(ps->first,p)==1)ans -= ps->first; if(gcd(ps->second,p)==1)ans += ps->second; } printf("%I64d\n",ans); }else{ scanf("%I64d %I64d",&i,&c); as[i]=c; } } } return 0; }

浙公网安备 33010602011771号