Co-prime hdu4135 初识容斥定理

题意:输入A,B,C 输出A-B 中与C互质的数的个数.

先处理出C的因子 

然后找1-(A-1)与C互质的数,找1-B 与C互质的数.相减就是答案.

现在问题就变成了如何快速求1-n与C互质的数.暴力判断肯定会超时.显然如果C的因子在范围内.C的因子倍数也不是与C互质的

比如2是C的因子 2 4 6 8 10...都不合法.3是C因子.3 6 9 12 15 ..不合法

可以注意到6重复了.找规律可以发现(蒙出来)如果是奇数个因子的答案就加起来,偶数就减去最后刚好是答案

#include <iostream>
#include <cstdio>
#include <math.h>
#include <cstring>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#define gmax(a,b) (a)=max((a),(b))
#define gmin(a,b) (a)=min((a),(b))
#define xh(i,m,n) for(int i=m;i<=n;i++)
#define ll long long
#define se(w) scanf("%lf",&w)
#define ss(o) scanf("%s",o)
#define sd(q) scanf("%lld",&q)
#define init(qwe) memset(qwe,0,sizeof(qwe));
#define finit(qwe) memset(qwe,-1,sizeof(qwe));
#define INF 0x3f3f3f3f
#define maxn 40005
#define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
#define MAXN 100005
#define gmax(a,b) (a)=max((a),(b))
#define gmin(a,b) (a)=min((a),(b))
#define ios0 ios_base::sync_with_stdio(0)
#define gc getchar()
using namespace std;

ll a,b,c,prime[1000005],cop[1000005],cpr[1000005];
void inite()
{
    init(prime);prime[1]=1;
    for(ll i=2;i<=1000004;i++)
    {
        if(prime[i]==0)
        {
            for(ll j=(i*i);j<1000005;j+=i)prime[j]=1;
        }
    }
    ll cnt=1;
    xh(i,2,1000004)
    if(!prime[i])cop[cnt++]=i;
}
ll getnum(ll asd,ll num)
{
    ll j,k,sign,sum,ss=0;
    for(ll i=1;i<1<<num;i++)
    {
        j=i;k=sign=0;sum=1;
            while(j)
            {
                if(j&1){
                    sum*=cpr[k];sign++;
                }
                j>>=1;k++;
            }
            if(sign%2)ss+=(asd/sum);
            else
            ss-=(asd/sum);
    }return ss;
}
int main()
{
    inite();
    int n;scanf("%d",&n);
    xh(casee,1,n)
    {   init(cpr);
        sd(a);sd(b);sd(c);ll cpc=c;ll j=1;ll k=0;
        while(cpc!=1&&cop[j]<=sqrt(cpc))
        {
            if(cpc%cop[j]==0){cpr[k++]=cop[j];while(cpc%cop[j]==0)cpc=cpc/cop[j];}j++;
        }
        if(cpc!=1)cpr[k++]=cpc;
        ll oo=b-getnum(b,k)-(a-getnum(a-1,k))+1;printf("Case #%d: %lld\n",casee,oo);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_35557621/article/details/81811787
今日推荐