【hdu 4135】Co-prime

【题目链接】:http://acm.hdu.edu.cn/showproblem.php?pid=4135

【题意】

让你求a..b中与n互质的数的个数.

【题解】

可以用前缀和转化为求1..x内与n互质的数的个数;
先求出n的所有的质因子;
然后设1..x内为第i个质因子的倍数的数的个数为ci;
则1..x内与n互质的数的个数就为
n-c1∪c2…∪clen
这个并可以用容斥原理搞出来;
ci = x/(第i个质因数)
因为是质因数,所以lcm就是这些数的乘积;
(更一般的情况,是求1..x内同时是a[1],a[2]..a[3]这些数的某一些数的倍数的数的个数,这时就不能直接乘了,而是lcm)

【Number Of WA

0

【反思】

加深对容斥原理的印象.

【完整代码】

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define Open() freopen("F:\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0)

typedef pair<int, int> pii;
typedef pair<LL, LL> pll;

const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
const double pi = acos(-1.0);
const int N = 30;

int two[N+5];
LL a, b, n;
vector <int> v;

LL cal(LL x){
    LL temp,ans = 0;int num;
    rep1(i,1,two[(int) v.size()]-1){
        temp = 1,num = 0;
        rep1(j,0,(int) v.size()-1)
            if (i&two[j]){
                temp*=v[j];
                num++;
            }
        if (num&1)
            ans += x/temp;
        else
            ans -= x/temp;
    }
    return ans;
}

void solve() {
    cin >> a >> b >> n;
    v.clear();
    for (LL i = 2;i*i <= n;i++)
        if (n%i == 0) {
            v.pb(i);
            while (n%i==0){
                n/=i;
            }
        }
    if (n > 1) v.pb(n);
    cout << b-cal(b)-(a-1-cal(a-1)) << endl;
}

int main() {
    //Open();
    Close();
    two[0] = 1;
    rep1(i,1,N) two[i] = two[i-1]*2;
    int T;
    cin >> T;
    rep1(TT,1,T){
        cout <<"Case #"<<TT<<": ";
        solve();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626225.html