Questionphp
參考html
題意
找出[a,b]中與n互質的數的個數
分析
一般咱們求1~n中與n互質的數的個數都是用歐拉函數.但若是n比較大或者是求1~m中與n互質的數的個數等等問題,要想時間效率高的話仍是用容斥原理。先對n分解質因數,分別記錄每一個質因數, 那麼所求區間內與某個質因數不互質的個數就是 m/r(i),假設r(i)是r的某個質因子 假設只有三個質因子, 總的不互質的個數應該爲p1+p2+p3-p1*p2-p1*p3-p2*p3+p1*p2*p3. pi表明m/r(i),即與某個質因子不互質的數的個數 ,當有更多個質因子的時候,能夠用狀態壓縮解決,二進制位上是1表示這個質因子被取進去了。 若是有奇數個1,就相加,反之則相減ios
容斥原理
求事件A、B、C的交集時,A U B U C=A+B+C-AB-AC-BC+ABC。函數
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define ll long long #define ull unsigned long long #define LOCAL using namespace std; const int maxn=5000+10; const int inf=0x3f3f3f3f; const int mod=1e9+7; vector<ll> v; ll a,b,n; void getPrime(ll n){//素數分解,要求的n較少時 v.clear(); for(ll i = 2;i*i<=n;i++){ if(n%i==0){ v.push_back(i); while(n%i==0) n/=i; } } if(n>1) v.push_back(n); return ; } ll solve(ll x,ll n){ getPrime(n); ll sum=0,val,cnt; for(ll i=1;i<(1<<v.size());i++){ val=1; cnt=0; for(ll j=0;j<v.size();j++){ if((1<<j)&i){ val*=v[j]; cnt++; } } if(cnt&1) sum+=x/val; else sum-=x/val; } return x-sum; } int main(){ int t; scanf("%d",&t); for(int i=1;i<=t;i++){ cin>>a>>b>>n; printf("Case #%d: %I64d\n",i,solve(b,n)-solve(a-1,n)); } return 0; }