GCD HDU - 1695(容斥原理)

Posted h-riven

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GCD HDU - 1695(容斥原理)相关的知识,希望对你有一定的参考价值。

要求从满足gcd(x, y) = k的对数,其中x属于[1, n], y属于[1, m]

gcd(x, y) = k 

==>gcd(x/k, y/k) =1

x/k属于[1, n/k], y/k属于[1, m/k]

又因为对数不可以重复,所以我可以限制对于gcd(x, y)中,让y>=x,这样就不会重复了,然后问题转化成了对于[1, n/k]区间内的每一个 i ,求 i 与 [i,m]中的数互质的对数,然后对于每一个 i 的答案相加求和

技术分享图片
#include<map>
#include<set>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x & (-x))
#define INOPEM freopen("in.txt", "r", stdin)
#define OUTOPEN freopen("out.txt", "w", stdout)

typedef unsigned long long int ull;
typedef long long int ll;
const double pi = 4.0*atan(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+50;
const int maxm = 1e9+10;
const int mod = 1e9+7;
using namespace std;

int n, m;
int T, tol;
bool pri[maxn];
vector<int> vec[maxn];

void handle() {
    memset(pri, true, sizeof pri);
    for(int i=2; i<maxn; i++) {
        if(pri[i]) {
            vec[i].push_back(i);
            for(int j=2; i*j<maxn; j++) {
                vec[i*j].push_back(i);
                pri[i*j] = false;
            }
        }
    }
}

ll solve(ll x, int k) {
    ll ans = 0;
    int len = vec[k].size();
    for(int i=1; i<(1<<len); i++) {
        int cnt = 0;
        ll tmp = 1;
        for(int j=0; j<len; j++) {
            if(i & (1<<j)) {
                cnt++;
                tmp *= vec[k][j];
            }
        }
        if(cnt & 1)    ans += x / tmp;
        else        ans -= x / tmp;
    }
    return ans;
}

int main() {
    handle();
    int cas = 1;
    int T;
    scanf("%d", &T);
    while(T--) {
        int a, b, k;
        scanf("%d%d%d%d%d", &a, &n, &b, &m, &k);
        if(k == 0) {
            printf("Case %d: 0
", cas++);
            continue;
        }
        n /= k, m /= k, k = 1;
        if(n > m)    swap(n, m);
        ll ans = 0;
        //[i, m]
        for(int i=1; i<=n; i++) {
            ans += 1ll * (m-i+1) - 1ll * (solve(m, i) - solve(1ll * (i-1), i));
        }
        printf("Case %d: %I64d
", cas++, ans);
    }
    return 0;
}
View Code

 

以上是关于GCD HDU - 1695(容斥原理)的主要内容,如果未能解决你的问题,请参考以下文章

HDU1695 GCD (欧拉函数+容斥原理)

GCD HDU - 1695(容斥原理)

hdu1695 GCD2 容斥原理 求x属于[1,b]与y属于[1,d],gcd(x,y)=k的对数。(5,7)与(7,5)看作同一对。

GCD HDU - 1695 (欧拉 + 容斥)

hdu 1695 GCD 欧拉函数 + 容斥

HDU1695-GCD(数论-欧拉函数-容斥)