HDU 1695 GCD 莫比乌斯反演

分析:简单的莫比乌斯反演

         f[i]为k=i时的答案数

         然后就很简单了

#include<iostream>
#include<algorithm>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int N=1e5+5;
int T,prime[N],mu[N],n,m;
bool vis[N];
void getmu()
{
    mu[1] = 1;
    int cnt = 0;
    for(int i=2; i<=N-5; i++)
    {
        if(!vis[i])
        {
            prime[cnt++] = i;
            mu[i] = -1;
        }
        for(int j=0; j<cnt&&i*prime[j]<=N-5; j++)
        {
            vis[i*prime[j]] = 1;
            if(i%prime[j]) mu[i*prime[j]] = -mu[i];
            else
            {
                mu[i*prime[j]] = 0;
                break;
            }
        }
    }
}
LL F(LL x){
   LL y=m/x;
   x=n/x;
   y-=x;
   return x*(x-1)/2+x+y*x;
}

int main(){
    getmu();
    scanf("%d",&T);
    int cas=0;
    while(T--){
      int k;
      scanf("%d%d%d%d%d",&n,&n,&m,&m,&k);
      if(n>m)swap(n,m);
      printf("Case %d: ",++cas);
      if(!k){
        printf("0\n");
        continue;
      }
      LL ans=0;
      int mx=min(n,m);
      for(int i=k;i<=mx;i+=k){
         ans+=mu[i/k]*F(i);
      }
      printf("%I64d\n",ans);
    }
    return 0;
}
View Code

 

posted @ 2016-04-22 17:59  shuguangzw  阅读(132)  评论(0编辑  收藏  举报