题目传送:#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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/u014355480/article/details/47733913