记录解决这道题过程中先后的疏忽
#include<bits/stdc++.h>using namespace std;long long t;
const long long N = 2e5 + 10;
long long n,a[N],ans;
long long Prime[N],tot,pos[N],p[N];
long long sum[N],num,h[N];
bool vis[N],v[N];void work() {for(long long i = 2;i < N;i++) {if(!vis[i]) Prime[++tot] = i;for(long long j = 1;j <= tot && i * Prime[j] < N;j++) {vis[i * Prime[j]] = 1;if(i % Prime[j] == 0) break;}}
}void solve() {for(long long i = 0;i <= n;i++) pos[i] = ans = sum[i] = num = v[i] = 0;cin >> n;for(long long i = 1;i <= n;i++) cin >> a[i];long long cnt = 0;for(long long i = 1;i <= n;i++) if(!vis[a[i]]) cnt++,p[a[i]]++;else h[a[i]]++; //漏了相同合数之间可以作为一对for(long long i = 1;i <= n;i++)if(!vis[a[i]] && p[a[i]]) sum[++num] = p[a[i]],p[a[i]] = 0;for(long long i = 1;i <= num;i++) {cnt -= sum[i]; //质数之间统计答案出错ans += cnt * sum[i];}for(long long i = 1;i <= n;i++)if(vis[a[i]])for(long long j = 2;j <= sqrt(a[i]);j++) {if(a[i] % j == 0) {long long tmp = a[i] / j;if(!vis[tmp] && !vis[j]) {pos[j]++;if(j != tmp) pos[tmp]++;ans++; //漏了合数自己跟自己可以构成一对答案v[a[i]] = 1;break;}}}for(int i = 1;i <= n;i++)if(h[a[i]] && v[a[i]]) ans += h[a[i]] * (h[a[i]] - 1) / 2,h[a[i]] = 0; //合数本身必须满足题意才能在相同合数之间配对for(long long i = 1;i <= n;i++)if(!vis[a[i]]) ans += pos[a[i]];cout << ans << '\n';
}signed main() {ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);work();cin >> t;while(t--) solve();return 0;
}