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).
//本题没想到好的方法,借用了某牛的思路才写过的!
//分析:题目是要求a<=x<=b,c<=y<=d(其中a,c题目中已经说了必为1),中有多少对(x,y)(无序的)满足GCD(x,y)=k,那么可以转化成求(x,y)分别在区间1<=x<=b/k,1<=y<=d/k中有多少对满足GCD(x,y)=1; 转换b/=k,d/=k,之后,假设b<=d,那么我们可以分两步来求值:
1、求[1,b]与[1,b]之间有多少对数互质,显然就是phi[1]+phi[2]+...phi[b]即可,用线性求欧拉函数的算法即可!
2\求[1,b]与[b+1,d]之间有多少对数互质,可以先求出有多少对数不互质,然后减去即可! 针对于区间[b+1,d]中得某一个数n求区间[1,b]中有多少个数与他不互质(即有公约数)那么可以用容斥原理较好的解决!
两步求值之和即为题意所求!
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define LL long long #define maxn 100005 int phi[maxn],x[maxn],cnt[1005]; void Init() { int i,j; memset(x,0,sizeof(x)); x[0]=x[1]=1; for(i=1;i<maxn;i++) phi[i]=i; for(i=2;i<maxn;i++) { if(!x[i]) { phi[i]=i-1; for(j=i*2;j<maxn;j+=i) { x[j]=1; phi[j]=phi[j]/i*(i-1); } } } } LL Imco_prime(int n,int m) { int i,j,t=0; for(i=2;i*i<=n;i++) { if(n&&n%i==0) { cnt[t++]=i; while(n&&n%i==0) n/=i; } } if(n>1) cnt[t++]=n; LL ans=0,tmp,flag; for(i=1;i<(1<<t);i++) { tmp=1,flag=0; for(j=0;j<t;j++) if(i&(1<<j)) flag++,tmp*=cnt[j]; if(flag&1) ans+=m/tmp; else ans-=m/tmp; } return ans; } int main() { Init(); int T,t=0,a,b,c,d,k,i,j; scanf("%d",&T); while(T--) { scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); if(k==0) { printf("Case %d: 0\n",++t); continue; } b/=k,d/=k; if(b>d) swap(b,d); LL ans=0,tmp=(LL)b*(d-b); //细节 for(i=1;i<=b;i++) ans+=phi[i]; for(i=b+1;i<=d;i++) tmp-=Imco_prime(i,b); printf("Case %d: %I64d\n",++t,ans+tmp); } return 0; }