数论+容斥——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