HDU 4135

http://acm.hdu.edu.cn/showproblem.php?pid=4135

求[A,B]内与N互素的数字个数

首先对N分解质因数,对于一个质因数,1-n与它不互素的数字个数是n/(这个质因数),这样可以得到m个集合(m是N分解出的质因数的个数),对这m个集合用容斥原理解出来它们的并集,再用总数去减

这里学习了用位运算求解容斥原理,非常简单,和状压dp中的位运算差不多感觉,注意容斥中奇加偶减

#include <iostream>

#include <cstdio>

#include <cstring>

#include <vector>

using namespace std;



typedef __int64 ll;



ll A,B,N;



vector <ll> v;



ll gao(ll n){

    int m=v.size();

    ll res=0;

    for(int i=1;i<(1<<m);i++){

        int cnt=0;

        ll temp=1;

        for(int j=0;j<m;j++){

            if(i&(1<<j)){

                cnt++;

                temp*=v[j];

            }

        }

        if(cnt&1)res+=n/temp;

        else res-=n/temp;

    }

    return n-res;

}



int main(){

    int T;

    scanf("%d",&T);

    for(int cas=1;cas<=T;cas++){

        scanf("%I64d%I64d%I64d",&A,&B,&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);

        printf("Case #%d: %I64d\n",cas,gao(B)-gao(A-1));

    }

    return 0;

}
View Code

 

你可能感兴趣的:(HDU)