HDU - 4135 Co-prime(容斥原理)

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;
}
相關文章
相關標籤/搜索