• hdu 5072 两两(不)互质个数逆向+容斥


    http://acm.hdu.edu.cn/showproblem.php?pid=5072

    求n个不同的数(<=1e5)中有多少组三元组(a, b, c)两两不互质或者两两互质。


    逆向求解,把所有不符合的情况求出来用总的情况数减去即可;

    先用容斥求出和a[i] 互质的个数num ,然后不符合条件的 就是 num*(n-1-num);

    求法见http://blog.csdn.net/u012774187/article/details/40399567



    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <stack>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define RD(x) scanf("%d",&x)
    #define RD2(x,y) scanf("%d%d",&x,&y)
    #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define clr0(x) memset(x,0,sizeof(x))
    typedef long long LL;
    const int maxn = 1e5+5;
    int n,p[maxn],cnt[maxn];//   公约数计数
    vector<int> q;
    int main() {
        int _;RD(_);while(_--){
            RD(n);
            for(int i = 1;i <= n;++i)
                RD(p[i]);
            clr0(cnt);
            for(int i = 1;i <= n;++i){
                for(int j = 1;j * j <= p[i];++j)if(p[i]%j == 0){
                    cnt[j]++;
                    if(p[i]/j != j)
                        cnt[p[i]/j]++;
                }
            }
            LL sub = 0;
            for(int i = 1;i <= n;++i){
                q.clear();
                int m = p[i];
                for(int j = 2;j * j <= m;++j)if(m%j == 0){
                    q.push_back(j);
                    while(m%j == 0)
                        m/=j;
                }
                if(m != 1)
                    q.push_back(m);
                int len = q.size();
                LL sum = 0;
                for(int j = 1;j < (1<<len);++j){
                    int cnt_fac = 0,u = 1;
                    for(int k = 0;k < len;++k)if(j & (1<<k)){
                        cnt_fac++;
                        u *= q[k];
                    }
                    if(cnt_fac & 1) sum += cnt[u];
                    else    sum -= cnt[u];
                }
                if(sum) sum--;
                sub += sum*(n - sum - 1);
            }
            printf("%I64d
    ",(LL)n*(n-1)*(n-2)/6 - sub/2);
        }
        return 0;
    }
    


  • 相关阅读:
    jpa入门案例----使用jpa对数据库进行查询、删除、修改操作
    ssm详细流程和步骤
    Dubbo
    ssm运行BUG
    mybatis 入门
    Linux
    Redis
    maven
    三层架构 开发模式
    转发和重定向的区别
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4049443.html
Copyright © 2020-2023  润新知