标签:hdu
http://acm.hdu.edu.cn/showproblem.php?pid=5072
1 5 1 3 9 10 2
4
/**
* @author neko01
*/
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define pb push_back
#define mp(a,b) make_pair(a,b)
#define clr(a) memset(a,0,sizeof a)
#define clr1(a) memset(a,-1,sizeof a)
#define dbg(a) printf("%d\n",a)
typedef pair<int,int> pp;
const double eps=1e-9;
const double pi=acos(-1.0);
const int INF=0x7fffffff;
const LL inf=(((LL)1)<<61)+5;
const int N=100005;
const int M=500;
bool isprime[M];
int prime[M];
int tot=0,n;
int fac[50];
bool have[N];
int a[N];
int s[N]; //sum[i]表示a[i]中能整除i的个数
void getprime()
{
for(int i=2;i<=M;i++)
{
if(isprime[i]) continue;
prime[tot++]=i;
for(int j=i*i;j<=M;j+=i)
isprime[i]=true;
}
}
LL gao()
{
LL ans=0;
for(int i=0;i<n;i++)
{
int m=a[i],num=0;
LL 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;
for(int j=1;j<(1<<num);j++)
{
int op=0,tmp=1;
for(int k=0;k<num;k++)
{
if((1<<k)&j)
{
tmp*=fac[k];
op++;
}
}
if(op&1) sum+=s[tmp];
else sum-=s[tmp];
}
if(sum==0) continue;
ans+=(sum-1)*(n-sum); //sum不互质的数包括了a[i]自身故减1
}
return ans/2;
}
int main()
{
int t;
scanf("%d",&t);
getprime();
while(t--)
{
scanf("%d",&n);
clr(have);
clr(s);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
have[a[i]]=true;
}
for(int i=2;i<N;i++)
for(int j=i;j<N;j+=i)
if(have[j]) s[i]++;
LL ans=(LL)n*(n-1)*(n-2)/6;
ans-=gao();
printf("%I64d\n",ans);
}
return 0;
}
hdu5072 Coprime 2014鞍山现场赛C题 计数+容斥
标签:hdu
原文地址:http://blog.csdn.net/neko01/article/details/40518947