1. 程式人生 > >Co-prime HDU

Co-prime HDU

Code:

#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; }