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("\n");// } 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\n",res); } return 0; }
原文地址:https://www.cnblogs.com/WindFreedom/p/9697075.html
时间: 2024-10-30 04:41:01