容斥的一个经典题型的变形。忘记ans清零怒WA七发。。
可以用改进的素数筛快速求出n个数中每个数的不互素数个数,效率大概是max(a[i])log(max(a[i]))。
虽然数据很水用暴力遍历每个数因数分解再进行容斥的方法也能过。。。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int num[100100],good[100100],cnt[100100],d[100100],n,m,a[100100];
long long solve(){
memset(good,1,sizeof(good));
memset(cnt,0,sizeof(cnt));
memset(d,0,sizeof(d));
long long ans=0;
for(int i=2;i<=a[n-1];i++){
if(good[i]){
if(d[i]==0){
d[i]=1;
}
int nn=0;
for(int j=1;i*j<=a[n-1];j++){
if(num[i*j]){
nn++;
}
}
for(int j=1;i*j<=a[n-1];j++){
if(d[i]==1&&j>1){
if(j%i==0){
good[i*j]=0;
}
else{
++d[i*j];
}
}
cnt[i*j]+=nn*(d[i]&1?1:-1);
}
}
if(num[i]==1&&cnt[i]>0){
ans+=(long long)(cnt[i]-1)*(n-cnt[i]);
}
}
return (long long)n*(n-2)*(n-1)/6-(ans/2);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(num,0,sizeof(num));
memset(nn,0,sizeof(nn));
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
num[a[i]]=1;
}
sort(a,a+n);
printf("%lld\n",solve());
}
return 0;
}