题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1695
2 1 3 1 5 1 1 11014 1 14409 9
Case 1: 9 Case 2: 736427HintFor the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).
思路:
以前,单纯的认为GCD和欧拉函数没有半毛钱的关系。
但是现在,这个关系就大了。。
GCD(X,Y)=K----->GCD(X/K,Y/K)=1
这样就是互质了。。
而这个题。我们枚举y,然后看前面x集合里面有多少和他互质的就是答案
至于说把计算这一种情况:在1-x区间,所有与y互质的个数,这个需要用到容斥原理(x<y)
我的代码:
#include<stdio.h> #include<algorithm> #include<vector> using namespace std; typedef __int64 ll; ll prime[100005]; bool flag[100005]; ll phi[100005]; vector<ll>link[100005]; void init()//得到素数以及欧拉函数值 { ll i,j,num=0; phi[1]=1; for(i=2;i<=100000;i++) { if(!flag[i]) { prime[num++]=i; phi[i]=i-1; } for(j=0;j<num&&prime[j]*i<=100000;j++) { flag[prime[j]*i]=true; if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; break; } else phi[i*prime[j]]=phi[i]*(prime[j]-1); } } for(j=1;j<=100000;j++)//得到所有数包含的素因子 { ll tmp=j; for(i=0;prime[i]*prime[i]<=tmp;i++) { if(tmp%prime[i]==0) { link[j].push_back(prime[i]); tmp=tmp/prime[i]; while(tmp%prime[i]==0) tmp=tmp/prime[i]; } if(tmp==1) break; } if(tmp>1) link[j].push_back(tmp); } } ll dfs(ll x,ll b,ll now)//容斥原理 { ll i,res=0; for(i=x;i<link[now].size();i++) res=res+b/link[now][i]-dfs(i+1,b/link[now][i],now); return res; } int main() { init(); ll i,a,b,t,T,ans,c,d,k; while(scanf("%I64d",&T)!=EOF) { for(t=1;t<=T;t++) { ans=0; scanf("%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&k); if(k==0||k>b||k>d) { printf("Case %I64d: 0\n",t); continue; } if(b>d) swap(b,d); b=b/k,d=d/k; for(i=1;i<=b;i++) ans=ans+phi[i]; for(i=b+1;i<=d;i++) ans=ans+b-dfs(0,b,i); printf("Case %I64d: %I64d\n",t,ans); } } return 0; }