传送门

据我所知有两种做法,思维难度都不大.

Ⅰ . Ⅰ. .

∑ i = l r ∑ j = i + 1 r a i ∗ a j \sum\limits_{i=l}^{r}\sum\limits_{j=i+1}^{r}a_i*a_j i=lrj=i+1raiaj

= ∑ i = l r a [ i ] ∗ ( p r e [ r ] − p r e [ i ] ) =\sum\limits_{i=l}^{r}a[i]*(pre[r]-pre[i]) =i=lra[i](pre[r]pre[i])

= p r e [ r ] ∗ ∑ i = l r a [ i ] − ∑ i = l r p r e [ i ] ∗ a [ i ] =pre[r]*\sum\limits_{i=l}^{r}a[i]-\sum\limits_{i=l}^{r}pre[i]*a[i] =pre[r]i=lra[i]i=lrpre[i]a[i]

这样,维护一个 p r e [ i ] pre[i] pre[i]数组,也就是 a i a_i ai的前缀和

维护一个 p r e [ i ] ∗ a [ i ] pre[i]*a[i] pre[i]a[i]的前缀和

这样可以 O ( 1 ) O(1) O(1)计算答案

typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 2e5+10;
class Solution {
public:
    long long pre[maxn],mul[maxn],w[maxn];
    vector<int> getSum(vector<int>& a, vector<int>& query) {
        int n = a.size();
        for(int i=0;i<n;i++)
            w[i+1] = a[i], pre[i+1]=(pre[i]+a[i])%mod;
        for(int i=1;i<=n;i++)
                mul[i] = (mul[i-1]+pre[i]*a[i-1]%mod)%mod;
        vector<int>ans;
        ans.clear();
        for(int i=1;i<query.size();i+=2)
        {
            int l = query[i-1], r = query[i];
            ll kl = ( pre[r]-pre[l-1])*pre[r]%mod;
            ll nxt = ( mul[r]-mul[l-1])%mod;
            ans.push_back(((kl-nxt)%mod+mod)%mod);
        }
        return ans;
    }
};

Ⅱ.

∑ i = l r ∑ j = i + 1 r a i ∗ a j \sum\limits_{i=l}^{r}\sum\limits_{j=i+1}^{r}a_i*a_j i=lrj=i+1raiaj

= 1 2 ∗ ∑ i = l r ∑ j = l r a i ∗ a j − ∑ i = l r a i 2 =\frac{1}{2}*\sum\limits_{i=l}^{r}\sum\limits_{j=l}^{r}a_i*a_j-\sum\limits_{i=l}^{r}a_i^2 =21i=lrj=lraiaji=lrai2

这样就更加简单

typedef long long ll;
const int N = 1e5 + 10, mod = 1e9 + 7;
class Solution {
public:
    ll sum1[N], sum2[N], n;
    
    vector<int> getSum(vector<int>& a, vector<int>& query) {
        // write code here
        n = a.size();
        for(int i = 1; i <= n; i++) 
		{
            sum1[i] = (sum1[i - 1] + a[i - 1]) % mod;
            sum2[i] = (sum2[i - 1] + 1l * a[i - 1] * a[i - 1] % mod) % mod;
        }
        vector<int> ans;
        for(int i = 0; i < query.size(); i += 2) 
		{
            int l = query[i], r = query[i + 1];
            ll sum = (sum1[r] - sum1[l - 1]) * (sum1[r] - sum1[l - 1]) % mod;
            sum -= sum2[r] - sum2[l - 1];
            ans.push_back(((sum % mod * 500000004) % mod + mod) % mod);
        }
        return ans;
    }
};