HDU 4135——Co-prime(容斥原理&&二進位制列舉)

ZMST發表於2018-10-25

題目連結:

模板

void prime(ll n)
{
    k=0;
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            Prime[k++]=i;
            while(n%i==0)
                n/=i;//這一步是把相同質因子除去,如12有兩個2
        }
    }
    if(n>1)
        Prime[k++]=n;
}
ll Find(ll num)
{
    ll ans=0,temp,flag;
    for(ll i=1;i<(ll)(1<<k);i++)
    {
        temp=1;
        flag=0;
        for(ll j=0;j<=k;j++)
        {
            if(i&(ll)(1<<j))
            {
                flag++;
                temp*=Prime[j];
            }
        }
        //cout<<temp<<endl;
        if(flag&1)
            ans+=num/temp;
        else
            ans-=num/temp;//奇加偶減
    }
    return ans;
}
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<queue>
#include<set>
using namespace std;
#define ll long long
#define maxn 1000010
ll a,b,n;
ll Prime[maxn];
int k;
void prime(ll n)
{
    k=0;
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            Prime[k++]=i;
            while(n%i==0)
                n/=i;//這一步是把相同質因子除去,如12有兩個2
        }
    }
    if(n>1)
        Prime[k++]=n;
}
ll Find(ll num)
{
    ll ans=0,temp,flag;
    for(ll i=1;i<(ll)(1<<k);i++)
    {
        temp=1;
        flag=0;
        for(ll j=0;j<=k;j++)
        {
            if(i&(ll)(1<<j))
            {
                flag++;
                temp*=Prime[j];
            }
        }
        //cout<<temp<<endl;
        if(flag&1)
            ans+=num/temp;
        else
            ans-=num/temp;//奇加偶減
    }
    return ans;
}
int main()
{
    int t;
    int flag=0;
    cin>>t;
    while(t--)
    {
        cin>>a>>b>>n;
        prime(n);
         cout<<"Case #"<<++flag<<": "<<b-a+1-Find(b)+Find(a-1)<<endl;
    }
    return 0;
}

參考連結:

https://blog.csdn.net/qq_36336399/article/details/76406320

https://blog.csdn.net/sand8o8time/article/details/76944025

https://blog.csdn.net/yu121380/article/details/79265704

相關文章