CF1884D题解
题目传送门。
思路
考虑暴力,首先我们能很容易得到一个
现在想想怎么优化到
由于
那么现在我们要求的就是
考虑枚举
那么得到答案为
显然的,对于
数论容斥:令
那么有
直接做即可,时间复杂度
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll Maxn=1e6+7;
ll T,n,b[Maxn],lmx[Maxn],a[Maxn],ans,p[Maxn];
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
scanf("%lld",&T);
while(T--){
scanf("%lld",&n);ans=0;
for(ll i=1;i<=n;i++) scanf("%lld",&a[i]),b[a[i]]++;
for(ll i=1;i<=n;i++)
for(ll j=i;j<=n;j+=i)
lmx[j]+=b[i];
for(ll i=n;i;i--){
for(ll j=i;j<=n;j+=i) p[i]+=b[j];
p[i]=(p[i]-1)*p[i]/2;
for(ll j=i<<1;j<=n;j+=i) p[i]-=p[j];
}
for(ll i=1;i<=n;i++){
if(!lmx[i]) ans+=p[i];
}
cout<<ans<<endl;
for(ll i=1;i<=n;i++) b[i]=a[i]=lmx[i]=p[i]=0;
}
return 0;
}
当然,我应该做复杂了,也许用不到数论容斥()