• hdu5072(容斥,互质判断,同色三角形模型)


    传送门

    解答传送门

    ac代码(位运算实现容斥原理):

    #include<bits/stdc++.h>
    #define per(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    typedef long long ll;
    //#define int long long
    const ll inf =2333333333333333LL;
    const double eps=1e-8;
    int read(){
        char ch=getchar();
        int res=0,f=0;
        while(ch<'0' || ch>'9'){f=(ch=='-'?-1:1);ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+(ch-'0');ch=getchar();}
        return res*f;
    }
    // ------------------------head
    #define mod 1000000007
    const int N=100005;
    int T,n,a[N],fac[N][10],fcnt[N],prime[N],pcnt,num[N];
    bool Notprime[N];
    void prime_sieve(){//线性筛
        memset(Notprime,false,sizeof(Notprime));
        pcnt=0;
        for(int i=2;i<=1000;i++){
            if(!Notprime[i])prime[pcnt++]=i;
            for(int j=0;j<pcnt&&i*prime[j]<=1000;j++){
                Notprime[i*prime[j]]=true;
                if(i%prime[j]==0)break;
            }
        }
    }
    void disi_num(int v,int pos){//disintegrate_num分解质因数
        fcnt[pos]=0;
        int _sqrt=sqrt(v);
        for(int i=2;i<=_sqrt;i++){
            if(v%i==0)fac[pos][fcnt[pos]++]=i;
            while(v%i==0)v/=i;
        }
        if(v>1)fac[pos][fcnt[pos]++]=v;
    }
    void count_num(){
        for(int i=2;i<=100000;i++){
            for(int j=i+i;j<=100000;j+=i){
                num[i]+=num[j];
            }
        }
    }
    ll in_ex(int pos){
        ll res=0;
        for(int i=1;i<(1<<fcnt[pos]);i++){
            int cnt=0,mut=1;
            for(int j=0;j<fcnt[pos];j++){
                if(i&(1<<j)){
                    cnt++;
                    mut*=fac[pos][j];
                }
            }
            if(cnt&1)res+=(ll)num[mut]-1;//减去a[pos]本身,因为他就是这都是它的质因数
            else res-=(ll)num[mut]-1;
        }
        return res;
    }
    
    signed main()
    {
        prime_sieve();
        scanf("%d",&T);
        while(T--){
            memset(num,0,sizeof(num));
            scanf("%d",&n);
            per(i,1,n){
                scanf("%d",&a[i]);
                num[a[i]]++;
                disi_num(a[i],i);
                //printf("i==%d ",i);//
                //per(j,0,fcnt[i]-1)printf("%d ",fac[i][j]);
                //printf("
    ");//
            }
            count_num();
            ll res=0;
            for(int i=1;i<=n;i++){
                ll tmp=in_ex(i);
                res+=(ll)(n-1-tmp)*tmp;
            }
            res=(ll)n*(n-1)*(n-2)/6-res/2;
            printf("%lld
    ",res);
        }
    
        return 0;
    }
  • 相关阅读:
    JavaScript 正则表达式
    git常用命令
    用纯css使内容永远居在页面底部
    Oracle中随机抽取N条记录
    表数据回复到某个时候
    oracle同名存储过程被覆盖后如何恢复(转)
    mybatis+spring+mysql
    定位
    关于js的闭包和复制对象
    idea展示runDashboard的窗口
  • 原文地址:https://www.cnblogs.com/WindFreedom/p/9697075.html
Copyright © 2020-2023  润新知