hdu4135 Co-prime(容斥原理)
阿新 • • 發佈:2018-12-10
題意:給定一個左端點L,右端點R,問L-R間有多少個數與N互質,注意1與任何數均互質。
題解:容斥原理,對N分解質因數,然後容斥原理找出這些質因數的倍數的個數,即與N不互質的數,
分別統計1-R中不互質,1-(L-1)中不互質,二者作差即為L-R中不互質,再用區間長度減去即為互質的個數。
Status | Accepted |
---|---|
Time | 15ms |
Memory | 1748kB |
Length | 1464 |
Lang | C++ |
Submitted | 2018-09-16 11:32:49 |
Shared | |
RemoteRunId | 26288227 |
Select Code
#include <iostream> #include <algorithm> #include <string> #include <cstring> #include <cstdio> #include <cmath> #include <set> #include <map> #include <vector> #include <stack> #include <queue> #include <bitset> const int INF=0x3f3f3f3f; const int mod=1e9+7; const double eps=1e-7; typedef long long ll; #define vi vector<int> #define si set<int> #define pii pair<int,int> #define pi acos(-1.0) #define pb push_back #define mp make_pair #define lowbit(x) (x&(-x)) #define sci(x) scanf("%d",&(x)) #define scll(x) scanf("%lld",&(x)) #define sclf(x) scanf("%lf",&(x)) #define pri(x) printf("%d",(x)) #define rep(i,j,k) for(int i=j;i<=k;++i) #define per(i,j,k) for(int i=j;i>=k;--i) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; ll l,r,m,num,a[40],len,ans; ll factor(ll n) { ll num=0; for(ll i=2;i*i<=n;++i) { if(n%i==0&&n) { a[num++]=i; while(n%i==0&&n)n/=i; } } if(n>1)a[num++]=n; return num; } ll func(ll up1,ll up2,ll m) { ll ans1=0,ans2=0,tmp,flag; rep(i,1,(1<<m)-1) { tmp=1,flag=0; rep(j,0,m-1) { if(i&(1<<j)) { ++flag; tmp*=a[j]; } } if(flag&1)ans1+=up1/tmp,ans2+=up2/tmp; else ans1-=up1/tmp,ans2-=up2/tmp; } return ans2-ans1; } void init() { num=0; mem(a,0); } int main() { int t; sci(t); rep(k,1,t) { init(); scanf("%lld%lld%lld",&l,&r,&m); len=r-l+1; num=factor(m); ans=len-func(l-1,r,num);//無需特判素數 分解自有天意 printf("Case #%d: %lld\n",k,ans); } return 0; }