Frieren Beyond Journey’s End Solution

考虑对a前缀和得s
$$
\sum_{i=1}^{n}\sum_{l=1}^{i}\sum_{r=i}^{n}\sum_{k=l}^{r}a_k
$$

$$
= \sum_{i=1}^{n}\sum_{l=1}^{i}\sum_{r=i}^{n}(s[r] - s[l - 1])
$$

$$
= \sum_{i=1}^{n}(\sum_{l=1}^{i}\sum_{r=i}^ns[r] - \sum_{l=1}^{i}\sum_{r=i}^ns[l - 1])
$$

$$
= \sum_{i=1}^{n}(\sum_{l=1}^{i}\sum_{r=i}^ns[r] - \sum_{r=i}^{n}\sum_{l=1}^is[l - 1])
$$

$$
= \sum_{i=1}^{n}(i * \sum_{r=i}^ns[r] - (n - i + 1) * \sum_{l=1}^is[l - 1])
$$

可以看出这两公式又可以前缀和 即对s前缀和得ss
$$
\sum_{r=i}^n s[r] = ss[n] - ss[i - 1]
$$

$$
\sum_{l=1}^i s[l - 1] = \sum_{l=0}^{i - 1}s[l] = ss[i - 1]
$$

带入进去

$$
= \sum_{i=1}^{n}(i * (ss[n] - ss[i - 1]) - (n - i + 1) * ss[i - 1])
$$

这个是公式变量只有 $i$, $O(N)$ 累加即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<bits/stdc++.h>
using namespace std;

const long long p = 1000000007;

int main(){
int T = 1;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<int> val(n + 1);
vector<long long> s(n + 1), ss(n + 1);
for (int i = 1; i <= n; i++) {
cin >> val[i];
s[i] = (s[i - 1] + val[i]) % p;
ss[i] = (ss[i - 1] + s[i]) % p;
}
long long res = 0;
for (long long i = 1; i <= n; i++) {
res += (ss[n] - ss[i - 1]) * i - ss[i - 1] * (n - i + 1);
res %= p;
}
cout << (res % p + p) % p << endl;
}
return 0;
}

复杂度$O(T * n)$

杂记

本道题在比赛两次被删, 在第三场比赛才放上去,呜呜,赛时过了4个(大佬前几场打了,后面就不打了,来了几个,估计是他们做出来的),本题是在学习单调栈时想到的题,用了该题的公式,简化了该题

2281. 巫师的总力量和 - 力扣(LeetCode)