hdu 5072 Coprime

来源:互联网 发布:迪奥布兰度 知乎 编辑:程序博客网 时间:2024/05/16 17:26

挑出数组a里 三个数满足三个数两两互质或者三个数两两不互质 。 

 反过来求就是可以用总的方案数 C(n,3) - (a,b互质, b,c不互质)          三个数中有 a和b互质,b和c 不互质 , a,c的关系无所谓,不管a,c是否互质,结果就可以是 与b不互质的与b互质的          我们都会吧情况多算了两次,所以 算出的总结果要除以2。。。问题就是求一个数组中与a[i]互质的有多少个, 防着写了一个代码

#include<bits/stdc++.h>using namespace std;int n;const int maxn = 100010;int a[maxn];long long s[maxn];bool isprime[maxn];int prime[maxn];int tot =0;int fac[100];//打出素数表void getprime(int M){    for(int  i = 2; i<=M; i++)    {        if(isprime[i])continue;        prime[tot++] = i;        for(int j = i+i; j<=M; j+=i)        {            isprime[j]  = true;        }    }}long long rongchi(){    long long ans = 0;    for(int i = 1; i<=n; i++)    {        int m =a[i];        int  num =0;        long long sum = 0;        for(int j =0; j<tot&&prime[j]*prime[j]<=m; j++)        {            if(m%prime[j]==0)            {                fac[num++] = prime[j];                while(m%prime[j]==0)                    m/=prime[j];            }        }        if(m!=1)fac[num++] = m;        // fac存下来每个数的因子        for(int j =1; j<(1<<num); j++)        {            int op=0;            int temp =1;            for(int k = 0; k<num; k++)            {                if((1<<k)&j)                {                    temp *= fac[k];                    op++;                }            }            if(op&1)            {                sum+=s[temp];            }            else            {                sum-=s[temp];            }        }        if(sum==0) sum =1;        ans+=(sum-1)*(n-sum);    }    return ans/2;}int flag[100000];int main(){    int T;    scanf("%d",&T);    memset(isprime,false,sizeof(isprime));    getprime(100000);    while(T--)    {        scanf("%d",&n);        memset(flag,0,sizeof(flag));        memset(s,0,sizeof(s));        int gm = 0;        for(int  i = 1; i<=n; i++)        {            scanf("%d",&a[i]);            flag[a[i]] =1;            gm= max(gm,a[i]);        }        //记录下来 s[i] 表示  在a中有多少个是可以整除 i的。        for(int i = 2; i<=gm; i++)        {            for(int j =i; j<=gm; j+=i)            {                if(flag[j])                    s[i]++;            }        }        printf("%lld\n",1LL*n*(n-1)*(n-2)/6 - rongchi());    }    return 0;}

0 0
原创粉丝点击