• hdu 1695 GCD 容斥+欧拉函数


    题目链接

    求 $ xin[1, a] , y in [1, b] $ 内 (gcd(x, y) = k)的(x, y)的对数。

    问题等价于$ xin[1, a/k] , y in [1, b/k] $ 内 (gcd(x, y) = 1) 的(x, y)的对数。

    假设a < b, 那么[1, a/k]这部分可以用欧拉函数算。 设 (iin (a/k, b/k]), (a/k, b/k]这部分可以用容斥算, 用a/k减去[1, a/k]里面和i不互质的数的个数。

    具体看代码。

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <complex>
    #include <cmath>
    #include <map>
    #include <set>
    #include <string>
    #include <queue>
    #include <stack>
    #include <bitset>
    using namespace std;
    #define pb(x) push_back(x)
    #define ll long long
    #define mk(x, y) make_pair(x, y)
    #define lson l, m, rt<<1
    #define mem(a) memset(a, 0, sizeof(a))
    #define rson m+1, r, rt<<1|1
    #define mem1(a) memset(a, -1, sizeof(a))
    #define mem2(a) memset(a, 0x3f, sizeof(a))
    #define rep(i, n, a) for(int i = a; i<n; i++)
    #define fi first
    #define se second
    typedef complex <double> cmx;
    typedef pair<int, int> pll;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int mod = 1e9+7;
    const int inf = 1061109567;
    const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    const int maxn = 1e5+5;
    ll phi[maxn];
    vector <int> v[maxn];
    void init() {
        phi[1] = 1;
        for(int i = 2; i<=100000; i++) {
            if(!phi[i]) {
                for(int j = i; j<=100000; j+=i ) {
                    if(!phi[j])
                        phi[j] = j;
                    phi[j] = phi[j]/i*(i-1);
                    v[j].pb(i);             //筛出j的素因子
                }
            }
            phi[i] += phi[i-1];             //维护前缀和
        }
    }
    int cal(int n, int b) {         //算[1, b]中和n互质的数的个数
        int len = v[n].size();
        int sum = 1<<len;
        int ret = 0;
        for(int i = 1; i < sum; i++) {
            int tmp = 1, cnt = 0;
            for(int j = 0; j<len; j++) {
                if((1<<j)&i) {
                    cnt++;
                    tmp *= v[n][j];
                }
            }
            if(cnt & 1)
                ret += b/tmp;
            else
                ret -= b/tmp;
        }
        return b-ret;
    }
    int main()
    {
        int cnt = 1, t, n, m, a, b, k;
        cin>>t;
        init();
        while(t--) {
            scanf("%d%d%d%d%d", &a, &a, &b, &b, &k);
            printf("Case %d: ", cnt++);
            if(a>b)
                swap(a, b);
            if(k == 0 || k>a||k>b) {
                puts("0");
                continue;
            }
            a /= k;
            b /= k;
            ll ans = phi[a];
            for(int i = a+1; i<=b; i++) {
                ans += cal(i, a);
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    软件工程二人组队开发第一周
    软件工程第五周
    这学期的目标
    软件工程第四周的总结
    二维数组的最大子数组和 时间复杂度:O(n的四次方)
    10.tesseract
    mysql存储过程和函数
    mysql触发器
    9.selenium
    mysql练习
  • 原文地址:https://www.cnblogs.com/yohaha/p/5319036.html
Copyright © 2020-2023  润新知