#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <algorithm> using namespace std; #define LL __int64 const LL maxn=1e5+10; LL prime[maxn+10]; LL phi[maxn+10],vis[maxn+10],num[maxn+10]; vector<LL> e[maxn]; void phi_table()//求出所有的欧拉函数 { LL i,j; for(i=2;i<=maxn;i++)phi[i]=0; phi[1]=1; for(i=2;i<=maxn;i++)if(!phi[i]) for(j=i;j<=maxn;j+=i) { if(!phi[j]) phi[j]=j; phi[j]=phi[j]/i*(i-1); } } void sieve() { LL i,j,m=(LL)sqrt(maxn+0.5); memset(vis,0,sizeof(vis)); for(i=2;i<=m;i++) { if(!vis[i]) for(j=i*i;j<=maxn;j+=i)vis[j]=1; } } void gen_primes()//求出素数表 { sieve(); LL i,c=0; for(i=2;i<=maxn;i++)if(!vis[i]) prime[c++]=i; } void init() //初始化 { LL i,j,k; phi_table(); gen_primes(); for(i=1;i<maxn;i++) { k=i; for(j=0;prime[j]*prime[j]<=k;j++) { if(k%prime[j]==0) { e[i].push_back(prime[j]);//储存i的所有质因子 while(k%prime[j]==0) k/=prime[j]; } } if(k>1)e[i].push_back(k); } } LL get_sum(LL a)//求a的二进制表示中1的个数,用于容斥法,奇加偶减 { LL s=0; while(a) { if(a&1) s++; a=a>>1; } return s; } LL dfs(LL a,LL b)//容斥法求1~b中与a不互质的个数 { LL t,i,j,k,ans=0,flag,s; t=e[a].size(); for(i=1;i<(1<<t);i++) { if(get_sum(i)%2)flag=1; else flag=-1; s=1; for(j=0;j<t;j++) { if(i&(1<<j))s*=e[a][j]; } ans+=flag*(b/s); } return ans; } int main() { LL L,a,b,c,d,k,i,j,sum,tt=0,T; init(); cin>>T; while(T--) { cin>>a>>b>>c>>d>>k; if(k==0||k>b||k>d) { cout<<"Case "<<++tt<<": 0"<<endl; continue; } if(b>d) swap(b,d); b/=k; d/=k; sum = 0; for(i=1;i<=b;i++) sum+=phi[i]; for(i=b+1;i<=d;i++) sum+=b-dfs(i,b); cout<<"Case "<<++tt<<": "<<sum<<endl; } return 0; } /* 本题简单化,a=c=1; 所以只用求1~x和1~y中有多少对gcd(p,q)==1,其中1<=p<=x,1<=q<=y,x=b/k,y=d/k; 因为如果gcd(p,q)==1,则gcd(p*k,q*k)==k(p*k<=b,q*k<=d) 由于跟p,q顺序无关,所以交换使x>y,并令p>q,则当1<=p<=y,时(p,qi)的个数就是phi[p],欧拉函数,表示不大于p的与p互质的个数; 当y<p<=x,可以通过求1~y中有多少个数与p不互质,反求互质的个数。判断1~y中有多少个数与p不互质,由于1~y中的数如果是p的某个质因子倍数数, 则必定不互质,否则必定互质。因而可以用容斥原理求。(奇加偶减) */
简化版:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <algorithm> using namespace std; #define LL __int64 const LL maxn=1e5+10; LL prime[maxn+10]; LL phi[maxn+10],vis[maxn+10],num[maxn+10]; LL e[maxn][7]; void init() //初始化 { LL i,j; for(i=2;i<=maxn;i++)phi[i]=0; phi[1]=1; memset(num,0,sizeof(num)); for(i=2;i<=maxn;i++) { if(!phi[i]) { for(j=i;j<=maxn;j+=i) { if(!phi[j]) phi[j]=j; phi[j]=phi[j]/i*(i-1); e[j][num[j]++]=i;//这里不要用vector,会超时的 } } } } LL dfs(LL a,LL b,LL c)//递归求容斥 { LL i,ans=0,t; for(i=a;i<num[c];i++) { t=b/e[c][i]; ans+=t-dfs(i+1,t,c); } return ans; } int main() { LL L,a,b,c,d,k,i,j,sum,tt=0,T; init(); cin>>T; while(T--) { cin>>a>>b>>c>>d>>k; if(k==0||k>b||k>d) { cout<<"Case "<<++tt<<": 0"<<endl; continue; } if(b>d) swap(b,d); b/=k; d/=k; sum = 0; for(i=1;i<=b;i++) sum+=phi[i]; for(i=b+1;i<=d;i++) { //sum+=b-dfs(i,b); sum+=b-dfs(0,b,i); } cout<<"Case "<<++tt<<": "<<sum<<endl; } return 0; }