题目链接:Coprime
题面:
1 5 1 3 9 10 2
4
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
bool status[100010];
int factor[100010][8];
int store[100010],cnt[100010];
long long ans[100010],res;
int one_amount[300];
int refl[300][8];
int cal[8];
void prep()
{
memset(refl,0,sizeof(refl));
int cont=0,temp;
for(int i=0;i<256;i++)
{
temp=i;
one_amount[i]=cont=0;
while(temp)
{
if(temp%2)
{
one_amount[i]++;
refl[i][cont]=1;
}
cont++;
temp/=2;
}
}
}
bool is_prime(int a)
{
if(a<=3)return true;
int x=sqrt(1.0*a);
for(int i=2;i<=x;i++)
{
if(a%i==0)
return false;
}
return true;
}
long long C(int x,int y)
{
long long res=1;
for(int i=1;i<=x;i++)
{
res=res*(y-i+1)/i;
}
return res;
}
int main()
{
int t,n,p,tmp;
long long temp;
scanf("%d",&t);
prep();
while(t--)
{
res=0;
memset(status,0,sizeof(status));
memset(factor,0,sizeof(factor));
memset(cnt,0,sizeof(cnt));
memset(ans,0,sizeof(ans));
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&store[i]);
for(int i=0;i<n;i++)
status[store[i]]=1;
for(int i=2;i<=100000;i++)
{
if(is_prime(i))
{
for(int j=i;j<=100000;j+=i)
{
if(status[j])
{
cnt[i]++;
}
p=0;
while(factor[j][p])
{
p++;
}
factor[j][p]=i;
}
}
else
{
for(int j=i;j<=100000;j+=i)
{
if(status[j])
{
cnt[i]++;
}
}
}
}
for(int i=0;i<n;i++)
{
tmp=store[i];
p=0;
while(factor[tmp][p])
{
cal[p]=factor[tmp][p];
p++;
}
if(p==0)
{
ans[i]=0;
continue;
}
tmp=1<<p;
for(int j=1;j<tmp;j++)
{
temp=1;
for(int k=0;k<p;k++)
{
if(refl[j][k])
{
temp=temp*cal[k];
}
}
if(one_amount[j]%2)
ans[i]+=cnt[temp];
else
ans[i]-=cnt[temp];
}
ans[i]-=1;
}
for(int i=0;i<n;i++)
{
res+=(ans[i]*(n-ans[i]-1));
}
res/=2;
printf("%I64d\n",C(3,n)-res);
}
return 0;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/david_jett/article/details/46815483