唉。。。这两天真是多灾多难啊。。。净碰到蛋疼的题。犯一些蛋疼的错误(这题是在一个判断的地方关系弄错了)。
这题的主要原理是多个集合的容斥原理。
代码如下:
#include"stdio.h" #include"math.h" __int64 prime[10005]={2,3},count=2; __int64 cnt,factor[20]; __int64 n,m,ans; void cal() { int i,j,flag; for(i=5;i<100000;i+=2) { flag=0; for(j=0;j<count;j++) if(i%prime[j]==0) {flag=1;break;} if(flag==0) prime[count++]=i; } } void cal1(int n) { int i,lim=(int)sqrt(n)+1; cnt=0; for(i=0;prime[i]<=lim&&n!=1;i++) { if(n%prime[i]==0) factor[cnt++]=prime[i]; while(n%prime[i]==0) n/=prime[i]; } if(n!=1) factor[cnt++]=n; } void rescure(int x,int sign,int num,int dcn,int d) { int i; if(sign==1) { num*=factor[d]; dcn++; } if(d+1==cnt) { if(num==1) return ; if(dcn%2==1) ans+=(n-x)/num; else ans-=(n-x)/num; return ; } for(i=0;i<=1;i++) rescure(x,i,num,dcn,d+1); } int main( ) { __int64 a,b,c,d,k,i,j,t,ncase=0; __int64 sum; cal(); scanf("%I64d",&t); while(t--) { ncase++; scanf("%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&k); printf("Case %d: ",ncase); if(k>b||k>d||k==0) { printf("0\n"); continue; } m=b<d?b/k:d/k; n=b>d?b/k:d/k; sum=n*m-m*(m+1)/2+1; ans=0; for(i=2;i<=m;i++) { cal1(i); for(j=0;j<=1;j++) rescure(i,j,1,0,0); } printf("%I64d\n",sum-ans); } return 0; }