HDU - 1695 GDU
莫比乌斯反演基础。
用rep 去掉重复的对数,rep一定是奇数( 因为有(1,1 ) )
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define fst first 4 #define scd second 5 #define pb(x) push_back((x)) 6 #define mkp(x,y) make_pair((x),(y)) 7 #define ist(x) insert((x)) 8 typedef long long ll; 9 typedef pair<int ,int > pii; 10 typedef pair<ll ,ll > pll; 11 typedef vector< int > vi; 12 ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b);} 13 ll qPow(ll a,ll b,ll mod){ ll ret=1ll;while(b){ if(b&1) ret=ret*a%mod;a=a*a%mod;b>>=1;} return ret; } 14 15 const int maxN=1e5+5; 16 bool check[maxN+10]; 17 int prime[maxN+10]; 18 int mu[maxN+10]; 19 void init(){ 20 memset(check,false,sizeof(check)); 21 mu[1]=1; 22 int tot=0; 23 for(int i=2;i<=maxN;++i){ 24 if(!check[i]) { prime[tot++]=i; mu[i]=-1; } 25 for(int j=0;j<tot;++j){ 26 long long k=i*prime[j];// may overflow , 27 if(k>maxN) break; 28 check[k]=true; 29 if(i%prime[j]==0){ mu[k]=0; break; } 30 else mu[k]=-mu[i]; 31 } 32 } 33 /* 34 for(int i=1;i<=100;++i) 35 printf(" mobi %d : %d\n",i,mu[i]); 36 */ 37 } 38 39 int main(){ 40 init(); 41 int T; 42 scanf("%d",&T); 43 for(int cntT=1;cntT<=T;++cntT){ 44 printf("Case %d: ",cntT); 45 int A,B,C,D,K; 46 scanf("%d%d%d%d%d",&A,&B,&C,&D,&K); 47 if(!K) { puts("0");continue; } 48 ll ans=0ll; 49 ll rep=0ll; 50 B/=K,D/=K; 51 int bound=min(B,D); 52 for(int i=1;i<=bound;++i) { 53 ans+=1ll*mu[i]*(B/i)*(D/i); 54 //printf("after %d : %lld\n",i,ans); 55 } 56 for(int i=1;i<=bound;++i) rep+=1ll*mu[i]*(bound/i)*(bound/i); 57 //printf(" \n%lld %lld\n",ans,rep); 58 printf("%lld\n",ans-rep/2); 59 } 60 return 0; 61 }
posted on 2018-08-06 11:47 Emiya_Kiritsugu 阅读(180) 评论(0) 编辑 收藏 举报