Prime Game 题解
题意
有一个长度为 \(n\) 的数列 \(a\),定义 \(f(p,q)\) 为 \(\prod\limits^i_{p\le i\le q} a_i\) 的质因子个数,求 \(\sum\limits^i_{1\le i\le n}\sum\limits^i_{i\le j\le n}f(i,j)\)。
解法
一般来说,这种题都需要拆贡献。
对于每个 \(1\le i\le n\),对其分解质因数。它其中的一个质因子 \(x\) 会对答案做出的贡献为 \((i-p_x)(n-i+1)\),其中 \(p_x\) 为数列中上一个带有质因子 \(x\) 的元素的下标。
理由如下:

如图,对于每个元素,只考虑以其为第一个带有质因子 \(x\) 的元素的区间。显然,这个区间的左端点在蓝色方框内,长度为 \(i-p_x\);右端点在紫色方框内,长度为 \(n-i+1\),两者相乘即为区间总数。
时间复杂度为 \(O(n\sqrt n)\),在 CF 的评测机上能用 1452 ms 过,所以注意常数。
code
// @_CuSO4_ 版权所有
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
ll a[1919810],p[1919810];
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin>>n;
for(ll i=1;i<=n;i++){
cin>>a[i];
}
ll ans=0;
for(ll i=1;i<=n;i++){
ll t=a[i];
for(ll j=2;j*j<=t;j++){
if(t%j==0){
ans+=(i-p[j])*(n-i+1);
p[j]=i;
}
while(t%j==0) t/=j;
}
if(t!=1){
ans+=(i-p[t])*(n-i+1);
p[t]=i;
}
}
cout<<ans<<endl;
return 0;
}

浙公网安备 33010602011771号