zoukankan      html  css  js  c++  java
  • GCD HDU

    要求从满足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
  • 相关阅读:
    WCF寻址
    WCF之多个协定
    WCF之多个终结点
    WCF客户端和服务端配置
    VS2012新建项目出错:未找到与约束ContractName Microsoft.VisualStudio.Text.ITextDocumentFactoryService
    windows运行打开服务命令
    Android中 服务里的方法抽取成接口
    Android Studio 使用genymotion 模拟器运行app时 提示找不到任何设备
    SVN 首次用TortoiseSVN Checkout 提示Unexpected HTTP status 405
    jQuery EasyUI -onblu、onkeyup等事件
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/9530573.html
Copyright © 2011-2022 走看看