zoukankan      html  css  js  c++  java
  • HDU1695 GCD [容斥]

    GCDGCD


    Descriptionmathcal{Description}
    nmk1<=x<=n,1<=y<=mgcd(x,y)==kx,y给出n、m、k ,求出1<=x<=n, 1<=y<=m 且gcd(x,y) == k 的(x,y)的对数.

    n,m,k<=105n,m,k<=10^5


    最初想法
    按照 能量采集 的方法.
    时间复杂度 O(NlogN)O(NlogN)

    #include<cstdio>
    #include<algorithm>
    #define reg register
    typedef long long ll;
    
    const int maxn = 100005;
    
    int Test_cnt;
    int T;
    int N;
    int M;
    int K;
    int cnt[maxn];
    
    void Work(){
            int a, c;
            scanf("%d%d%d%d%d", &a, &N, &c, &M, &K);
            if(!K || K > N || K > M){ printf("0
    "); return ; }
            int Lim = std::min(N, M);
            for(reg int d = Lim; d >= K; d --){
                    cnt[d] = (N/d) * (M/d);
                    for(reg int i = 2; i*d <= Lim; i ++) cnt[d] -= cnt[i*d];
            }
            printf("Case %d: %d
    ", ++ Test_cnt, cnt[K]);
    }
    
    int main(){
            scanf("%d", &T);
            while(T --) Work();
            return 0;
    }
    
    

    正解部分
    然而上面的方法连样例都过不去 , 为什么呢?
    假设 N<MN<M, 因为在 NNMM 的重合部分会有重复计算,
    所以要减去这些重复的计算, 再计算一次 NNNN 之间的答案, 除22后与NNMM得出的答案作差即可.

    时间复杂度同上 .


    实现部分
    没什么好说的 .

    #include<cstdio>
    #include<algorithm>
    #define reg register
    typedef long long ll;
    
    const int maxn = 200005;
    
    int Test_cnt;
    int T;
    ll N;
    ll M;
    ll K;
    ll cnt[maxn];
    
    void Work(){
            ll a, c;
            scanf("%lld%lld%lld%lld%lld", &a, &N, &c, &M, &K);
            if(K > N || K > M){ printf("Case %d: 0
    ", ++ Test_cnt); return ; }
            ll Lim = std::min(N, M);
            for(reg ll d = Lim; d >= 1; d --){
                    cnt[d] = (N/d) * (M/d);
                    for(reg ll i = 2; i*d <= Lim; i ++) cnt[d] -= cnt[i*d];
            }
            ll Ans = cnt[K];
            for(reg ll d = Lim; d >= 1; d --){
                    cnt[d] = (Lim/d) * (Lim/d);
                    for(reg ll i = 2; i*d <= Lim; i ++) cnt[d] -= cnt[i*d];
            }
            printf("Case %d: %lld
    ", ++ Test_cnt, Ans-(cnt[K]>>1));
    }
    
    int main(){
            scanf("%d", &T);
            while(T --) Work();
            return 0;
    }
    
  • 相关阅读:
    java中bean和xml相互转换
    java操作zip文件
    java内置的解压缩工具
    java操作Excel简单入门
    java开发IDEA插件入门
    java中Class.getResourceAsStream()和ClassLoader.getResourceAsStream()的区别
    java中文转拼音
    vue父子组件通信
    学会使用box-sizing布局
    webpack-dev-server 导致的 invalid host header
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822569.html
Copyright © 2011-2022 走看看