[前缀和]P2671 [NOIP 2015 普及组] 求和 题解
朴素的前缀和优化题
阅读题面,发现在题目中 \(x , y , z\) 的三元组中 \(y\) 没有用,相当于是任意两个下标同奇偶的 \(x , z\) 进行操作。
把式子拆一下
\[(x + z) \times (num_x + num_z)
\]
\[= x \times num_x + z \times num_x + x \times num_z + z \times num_z
\]
然后发现这些东西全部可以预处理。把含 \(x\) 的项分离出来之后,分四个数组分奇偶从后往前做前缀和就行。
#include <bits/stdc++.h>
#define int long long
constexpr int N = 1e5 + 5;
constexpr int mod = 10007;
using namespace std;
int ans , n , m , num[N] , colour[N] , sum1[N][2] , sum2[N][2] , sum3[N][2] , sum4[N][2];
signed main() {
cin >> n >> m;
for(register int i = 1; i <= n; ++i) {
cin >> num[i];
}
for(register int i = 1; i <= n;++i) {
cin >> colour[i];
}
for(register int i = n; i; --i) {
ans = (ans + (i * num[i] * sum1[colour[i]][i & 1] + num[i] * sum2[colour[i]][i & 1] + i * sum3[colour[i]][i & 1] + sum4[colour[i]][i & 1]) % mod) % mod;
sum1[colour[i]][i & 1] ++;
sum2[colour[i]][i & 1] += i;
sum3[colour[i]][i & 1] += num[i];
sum4[colour[i]][i & 1] += i * num[i];
}
cout << ans;
return 0;
}

浙公网安备 33010602011771号