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 }
View Code

 

posted on 2018-08-06 11:47  Emiya_Kiritsugu  阅读(180)  评论(0编辑  收藏  举报

导航