Co-prime HDU - 4135_容斥计数
题目过于智障,不用解释
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> using namespace std; const int maxn=100000+233; typedef long long ll; int v[maxn],vis[maxn]; int m[maxn]; int num; //质因子个数 ll ans=0; ll A,B; ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} void init(ll N){ int range=(int)sqrt(N),cnt=0; for(int i=2;i<=range;++i){ if(!vis[i])v[++cnt]=i; for(int j=1;j<=cnt&&v[j]*i<=range;++i){ vis[i*v[j]]=1; if(i%v[j]==0)break; } } ll t=N; for(int i=1;i<=cnt;++i)if(N%v[i]==0)m[++num]=v[i]; for(int i=1;i<=num&&t!=1;++i)while(t%m[i]==0)t/=m[i]; if(t>range)m[++num]=t; } void dfs(int cur,ll lcm,int id) { if(cur>num)return; lcm=m[cur]/gcd(m[cur],lcm)*lcm; if(id) ans+=(B/lcm)-((A-1)/lcm); else ans-=(B/lcm)-((A-1)/lcm); for(int i=cur+1;i<=num;++i) dfs(i,lcm,!id); } int main() { int T;scanf("%d",&T); for(int cas=1;cas<=T;++cas) { memset(v,0,sizeof(v)); memset(vis,0,sizeof(vis)); memset(m,0,sizeof(m)); num=ans=0; ll N; scanf("%lld%lld%lld",&A,&B,&N); init(N); for(int i=1;i<=num;++i) dfs(i,m[i],1); printf("Case #%d: %lld\n",cas,B-A-ans+1); } return 0; }