其他分享
首页 > 其他分享> > 数论+容斥——cf1295D

数论+容斥——cf1295D

作者:互联网

/*
d=(a,m),a=pd,m=qd,(p,q)=1 
(pd+x,qd)=d,设x=td 
(pd+td,qd)=d  => (p+t,q)=1 => (p',q)=1,p<=p'<p+q
处理出q的所有质因子,然后用这些质因子在区间[p,p+q-1]里筛 

*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long 

ll T,a,m,d;
ll prime[20],mm;

void divide(ll x){
    mm=0;
    for(ll i=2;i*i<=x;i++){
        if(x%i==0){
            prime[mm++]=i;
            while(x%i==0)
                x/=i;
        }
    }
    if(x>1)
        prime[mm++]=x;
}

ll solve(ll x){//求[1,x]里x没被prime筛掉的个数
    if(x==0)return 0; 
    ll sum=0;//被筛掉的个数 
    for(int s=1;s<(1<<mm);s++){
        ll mul=1,cnt=0;
        for(int i=0;i<mm;i++)
            if((s>>i) & 1)mul*=prime[i],cnt++;
        if(cnt%2==0)
            sum-=x/mul; 
        else
            sum+=x/mul;
    }
    return x-sum;
}

int main(){
    ll T;cin>>T; 
    while(T--){
        cin>>a>>m;
        d=__gcd(a,m);
        ll p=a/d,q=m/d;
        divide(q);
        
        cout<<solve(p+q-1)-solve(p-1)<<'\n'; 
    }
}

 

标签:prime,数论,ll,容斥,qd,pd,mul,sum,cf1295D
来源: https://www.cnblogs.com/zsben991126/p/12259200.html