把1000以内的素数打表,然后用两个数分别表示当前数和他应该乘的数,ans+=他应该乘的数的个数, 当前数的个数加一
#include <bits/stdc++.h> using namespace std; int flag[1000006]; int prime[1009],N=0; void init() { prime[N++]=2; int j=2; for(int i=3;i<=1007;i++) {for(j=2;j*j<=i;j++) { if(i%j==0)break; } if(j*j>i)prime[N++]=i; } } int main() { int t; init(); scanf("%d",&t); while(t--) { int n,x; scanf("%d",&n); memset(flag,0,sizeof(flag)); int ans=0; for(int i=1;i<=n;i++) { scanf("%d",&x); long long a=1,b=1; int flag1=0; for(int i=0;i<N&&prime[i]<=x;i++) { int tmp=prime[i]*prime[i]*prime[i]; while(x%tmp==0)x/=tmp; if(x%(prime[i]*prime[i])==0) { a*=prime[i]*prime[i]; b*=prime[i]; x/=(prime[i]*prime[i]); } if(x%prime[i]==0) { a*=prime[i]; b*=prime[i]*prime[i]; x/=prime[i]; } if(b>1e6)flag1=1; if(flag1)break; } if(flag1)continue; if(x>prime[N-1])continue; ans+=flag[b]; //cout<<b<<" "<<flag[b]<<endl; flag[a]++; } printf("%d\n",ans); } return 0; }