#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+3;
vector<int>v[N],dv[N],idx[N];//v[i]:储存i的所有因数 idx[i]:储存i在序列中出现的位置
int f[N],g[N],n,a[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i) {//O(n*logn)
scanf("%d",&a[i]);
for(int j=i;j<=n;j+=i) {//调和级数
v[j].push_back(i);//O(n*logn)的复杂度来求1-n所有数的因子
}
}
for(int i=1;i<=n;++i){
for(int j:v[a[i]]){
idx[j].push_back(i);
}
}
ll res=0;
for(int i=2;i<n;++i) {
vector<int> tt=v[a[i]];
reverse(tt.begin(),tt.end());
for(auto j:tt) {//容斥原理
f[j]+=lower_bound(idx[j].begin(),idx[j].end(),i)-idx[j].begin();
//f[i]: 表示当前位置 (i) 之前的序列当中与当前位置最大公约数是j的数的个数
g[j]+=idx[j].end()-upper_bound(idx[j].begin(),idx[j].end(),i);
//g[i]: 表示当前位置 (i) 之后的序列当中与当前位置最大公约数是j的数的个数
for(int k:v[j]){//由于要求最大公约数,j的所有因子要减去j所占的权重
if(j!=k){
f[k]-=f[j];g[k]-=g[j];
}
}
}
ll ans=0;
for(int j:v[a[i]]){
ans+=f[j];
res+=ans*g[j];
f[j]=g[j]=0;
}
}cout<<res<<'\n';
return 0;
}```
2022_1 _10_56_D
最新推荐文章于 2024-10-10 22:59:02 发布