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\) 的元素的下标。


理由如下:

image

如图,对于每个元素,只考虑以其为第一个带有质因子 \(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;
}
posted @ 2025-05-03 16:39  _CuSO4  阅读(42)  评论(1)    收藏  举报