HDU-1695-GCD(Mobius反演/容斥)

来源:互联网 发布:上饶招聘中年淘宝模特 编辑:程序博客网 时间:2024/05/22 14:20


Sample Input
21 3 1 5 11 11014 1 14409 9
 

Sample Output
Case 1: 9Case 2: 736427
Hint
For the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).
 


题意:a,b,c,d,m,  0<=x<=b,0<=y<=d,求满足gcd(x,y)=m这样的数对(x,y)的数量 

题解:


 

CODE:

#include <iostream>#include <cstdio>#include <vector>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <set>#include <map>#include <queue>#include <stack>using namespace std;#define LL long longconst int N = 100010;int mu[N];void getMu(){    for (int i = 1; i < N; ++i)    {        int target = i == 1 ? 1 : 0;        int delta = target - mu[i];        mu[i] = delta;        for (int j = 2 * i; j < N; j += i)            mu[j] += delta;    }}bool check[N];int prime[N];void Moblus(){    memset(check,false, sizeof(check));    mu[1]=1;    int tot = 0;    for(int i=2; i<=N; ++i)    {        if(!check[i])        {            prime[tot++]=i;            mu[i]=-1;        }        for(int j=0; j<tot; ++j)        {            if(i*prime[j]>N)break;            check[prime[j]*i] =true;            if(i%prime[j]==0)            {                mu[i*prime[j]]=0;                break;            }            else                mu[i*prime[j]]=-mu[i];        }    }}int a,b,c,m;int main(){    //getMu();    Moblus();    int T;    scanf("%d", &T);    int cas=1;    while(T--)    {        scanf("%d%d%d%d%d",&c,&a,&c,&b,&m);        if(m==0){printf("Case %d: 0\n",cas++);continue;}        if(a>b)swap(a,b);        LL ans=0;        a/=m,b/=m;        for(int i=1; i<=a; ++i)            ans-=(LL)mu[i]*(a/i)*(a/i);        ans/=2;        for(int i=1; i<=a; ++i)            ans+=(LL)mu[i]*(a/i)*(b/i);        printf("Case %d: %I64d\n",cas++,ans);    }    return 0;}



另外容斥解法:


#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <cmath>#include <set>#include <vector>#define INF 0x3f3f3f3fusing namespace std;#define N 100005int a,b,c,k,mod;vector<int> x[N];bool is[N];void get_prime(){    memset(is,0,sizeof(is));    for(int i=0; i<N; ++i)        x[i].clear();    for(int i=2; i<N; i+=2)x[i].push_back(2);    for(int i=3; i<N; i+=2)        if(!is[i])        {            for(int j=i; j<N; j+=i)            {                is[j]=1;                x[j].push_back(i);            }        }}long long solve(long long m, long long n){    long long sum=0;    for(int i=1; i<1<<x[n].size(); ++i)    {        int cnt=0;        int val=1;        for(int j=0; j<x[n].size(); ++j)        {            if(i&(1<<j))            {                val*=x[n][j];                ++cnt;            }        }        if(cnt&1)sum+=m/val;        else sum-=m/val;    }    return m-sum;}int main(){    int T;    get_prime();    scanf("%d",&T);    int cas=1;    while(T--)    {        long long ans=0;        scanf("%d%d%d%d%d",&c,&a,&c,&b,&k);        if (k == 0)        {            printf("Case %d: 0\n", cas++);            continue;        }        a/=k;        b/=k;        if(a>b)swap(a,b);        for(int i=1; i<=b; ++i)            //for(int j=1; j<=i&&j<=a; ++j)            {                ans+=solve(min(i,a),i);            }        printf("Case %d: %I64d\n",cas++,ans);        //cout<<ans<<endl;    }    return 0;}


0 0
原创粉丝点击