計算
題目傳送:#1116 : 計算
這裏說下sum,pre,suf,ji數組的含義:
sum:所求答案
pre:所有前綴積之和
suf:所有後綴積之和
ji:區間內所有數之積
以一個例子說明:
比如我們現在正在合併區間{3,4},{2,5}
而區間{3,4}
所表示的
sum1=3 + 4 + 3 * 4 = 19
pre1 = 3 + 3 * 4 = 12
suf1 = 3 * 4 + 4 = 16
ji1 = 3 * 4 = 12
而區間{2,5}
sum2 = 2 + 5 + 2 * 5 = 17
pre2 = 2 + 2 * 5 = 12
suf2 = 2 * 5 + 5 = 15
ji2 = 2 * 5 = 10
合併的時候:
sum = sum1 + sum2 + 3 * 4 * 2 + 3 * 4 * 2 * 5 + 4 * 2 + 4 * 2 * 5
即sum = sum1 + sum2 + suf1 * pre2
不過也要同時記得更新ji,pre和suf數組
AC代碼:
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;
#define MOD 10007
int n, q;
const int maxn = 100005;
int sum[maxn << 2];//此節點所表示區間內的所有子序列的乘積之和,即輸出答案爲sum[1]
int ji[maxn << 2];//此節點所表示區間內各個數之積
int pre[maxn << 2];//此節點所表示的區間處於合併時的後綴時所對合並後的區間的貢獻
int suf[maxn << 2];//此節點所表示的區間處於合併時的前綴時所對合並後的區間的貢獻
void pushup(int rt, int m) {
ji[rt] = ji[rt << 1] * ji[rt << 1 | 1] % MOD;
sum[rt] = (sum[rt << 1] + sum[rt << 1 | 1] + suf[rt << 1] * pre[rt << 1 | 1]) % MOD;
pre[rt] = (pre[rt << 1] + ji[rt << 1] * pre[rt << 1 | 1]) % MOD;
suf[rt] = (suf[rt << 1 | 1] + ji[rt << 1 | 1] * suf[rt << 1]) % MOD;
}
void build(int rt, int l, int r) {
sum[rt] = 0;
pre[rt] = 0;
suf[rt] = 0;
ji[rt] = 0;
if(r == l) {
return;
}
int mid = (l + r) >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
}
void update(int rt, int l ,int r, int p, int x) {
if(l == r && l == p) {
sum[rt] = x % MOD;
pre[rt] = x % MOD;
suf[rt] = x % MOD;
ji[rt] = x % MOD;
return;
}
int mid = (l + r) >> 1;
if(p <= mid) update(rt << 1, l, mid, p, x);
else update(rt << 1 | 1, mid + 1, r, p, x);
pushup(rt, r - l + 1);
}
int main() {
scanf("%d %d", &n, &q);
build(1, 1, n);
for(int i = 0; i < q; i ++) {
int p, x;
scanf("%d %d", &p, &x);
update(1, 1, n, p, x);
printf("%d\n", sum[1]);
}
return 0;
}