版权声明: https://blog.csdn.net/blackneed/article/details/81805501
计算
时间限制:4000ms
单点时限:1000ms
内存限制:256MB
描述
现在有一个有n个元素的数组a1, a2, ..., an。
记f(i, j) = ai * ai+1 * ... * aj。
初始时,a1 = a2 = ... = an = 0,每次我会修改一个ai的值,你需要实时反馈给我 ∑1 <= i <= j <= n f(i, j)的值 mod 10007。
输入
第一行包含两个数n(1<=n<=100000)和q(1<=q<=500000)。
接下来q行,每行包含两个数i, x,代表我把ai的值改为了x。
输出
分别输出对应的答案,一个答案占一行。
样例输入
5 5 1 1 2 1 3 1 4 1 5 1
样例输出
1 3 6 10 15
解题,可以看大佬传送门
想出来就很容易的线段树了,手打了一遍大佬的AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int maxn = 100005;
#define MOD 10007
int sum[maxn<<2];
int ji[maxn<<2];
int pre[maxn<<2];
int suf[maxn<<2];
int n,q;
void PushUp(int re){
ji[re] = ji[re<<1]*ji[re<<1|1]%MOD;
sum[re] = (sum[re<<1] + sum[re<<1|1] + suf[re<<1]*pre[re<<1|1])%MOD;
pre[re] = (pre[re<<1] + ji[re<<1]*pre[re<<1|1])%MOD;
suf[re] = (suf[re<<1|1] + ji[re<<1|1]*suf[re<<1])%MOD;
}
void BuildTree(int re,int l,int r){
sum[re] = 0;
ji[re] = 0;
pre[re] = 0;
suf[re] = 0;
if(l==r) return;
int mid = (l+r)>>1;
BuildTree(re<<1,l,mid);
BuildTree(re<<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);
}
int main() {
scanf("%d %d", &n, &q);
BuildTree(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;
}