关于此题Codeforces Round 1003 (Div. 4)_G. Skibidus and Capping
记录解决这道题过程中先后的疏忽
#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;
}