[bzoj 1101--Poi2007]Zap
2017-11-26 16:06
435 查看
FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d。作为FGD的同学,FGD希望得到你的帮助。
莫比乌斯反演的处女题。其实还是较水的,首先先把a%d,b%d,这样问题便简化成求gcd(x,y)=1的对数了。f(i)表示的是gcd(x,y)=i的对数,F(i)表示的是gcd(x,y)%i=0的对数,那问题又简化成求f(1)。
熟悉莫比乌斯的同学明白在知道f与F的含义后,这题便可做了。
莫比乌斯反演的处女题。其实还是较水的,首先先把a%d,b%d,这样问题便简化成求gcd(x,y)=1的对数了。f(i)表示的是gcd(x,y)=i的对数,F(i)表示的是gcd(x,y)%i=0的对数,那问题又简化成求f(1)。
熟悉莫比乌斯的同学明白在知道f与F的含义后,这题便可做了。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; int pr=0,prime[51000]; bool v[51000]; long long Mu[51000],sM[51000]; void get_Mu() { memset(v,true,sizeof(v)); Mu[1]=sM[1]=1; for(int i=2;i<=50000;i++) { if(v[i]==true) { prime[++pr]=i; Mu[i]=-1; } for(int j=1;(j<=pr && i*prime[j]<=50000);j++) { v[i*prime[j]]=false; if(i%prime[j]==0) { Mu[i*prime[j]]=0; break; } Mu[i*prime[j]]=-Mu[i]; } sM[i]=sM[i-1]+Mu[i]; } } long long find(int x,int y) { if(x>y)swap(x,y); int last=0;long long s=0; for(int i=1;i<=x;i=last+1) { last=min(x/(x/i),y/(y/i)); s+=(sM[last]-sM[i-1])*(x/i)*(y/i); } return s; } int main() { get_Mu(); int t; scanf("%d",&t); while(t--) { int a,b,d; scanf("%d%d%d",&a,&b,&d); if(d==0) { printf("0\n"); continue; } long long ans=0; ans=find(a/d,b/d); printf("%lld\n",ans); } return 0; }
相关文章推荐
- BZOJ 1101: [POI2007]Zap|莫比乌斯反演
- 【BZOJ】【1101】【POI2007】Zap
- bzoj1101[POI2007]Zap-莫比乌斯反演
- [莫比乌斯反演] BZOJ1101: [POI2007]Zap
- BZOJ 1101([POI2007]Zap-满足x<=a&&y<=b&&gcd(x,y)=d的数对个数)
- 【bzoj1101】[POI2007]Zap
- 【莫比乌斯反演+分块】BZOJ1101-[POI2007]Zap
- [BZOJ]1101: [POI2007]Zap
- BZOJ1101 [POI2007] Zap
- 【BZOJ 1101】 [POI2007]Zap
- bzoj 1101: [POI2007]Zap
- bzoj 1101: [POI2007]Zap
- BZOJ 1101 [POI2007]Zap ——Dirichlet积
- BZOJ 1101 [POI2007]Zap 莫比乌斯反演
- bzoj 1101 [POI2007]Zap 莫比乌斯反演
- bzoj1101 [POI2007]ZAP-Queries(莫比乌斯反演)
- BZOJ 1101: [POI2007]Zap 莫比乌斯反演
- 【莫比乌斯反演】BZOJ1101 [POI2007]zap
- BZOJ 1101: [POI2007]Zap( 莫比乌斯反演 )
- bzoj2045: 双亲数&bzoj1101: [POI2007]Zap