hihocoder-1116 : 计算 (线段树区间合并)

来源:互联网 发布:阿里云域名备案多少钱 编辑:程序博客网 时间:2024/05/18 03:53

描述

现在有一个有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 51 12 13 14 15 1
样例输出
1361015

#include <stdio.h>#include <string.h>#include <ctime>#include <stack>#include <string>#include <algorithm>#include <iostream>#include <cmath>#include <map>#include <queue>#include <vector>using namespace std;#define LL long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define lowbit(x) (x&-x)#define mem(x,a) memset(x,a,sizeof(x))const int maxn = 5e5 + 5;const int INF = 0x3f3f3f3f;const int mod = 10007;int ans[maxn], sum[maxn], lbd[maxn], rbd[maxn];int readint(){int ret = 0, sgn = 1;char c = getchar();while (c != '-' && (c<'0' || c>'9')) c = getchar();sgn = (c == '-') ? -1 : 1;ret = (c == '-') ? 0 : (c - '0');while (c = getchar(), c >= '0'&&c <= '9'){ret = ret * 10 + c - '0';}return ret*sgn;}void pushUp(int rt){int ls = rt << 1, rs = rt << 1 | 1;sum[rt] = (sum[ls] * sum[rs]) % mod;lbd[rt] = (lbd[ls] + sum[ls] * lbd[rs]) % mod;rbd[rt] = (rbd[rs] + sum[rs] * rbd[ls]) % mod;ans[rt] = ((ans[ls] + ans[rs]) + (lbd[rs] * rbd[ls]) % mod) % mod;}void update(int x, int c, int l, int r, int rt){if (l == r){ans[rt] = sum[rt] = lbd[rt] = rbd[rt] = c;return;}int m = (l + r) >> 1;if (x <= m)update(x, c, lson);elseupdate(x, c, rson);pushUp(rt);}int main(){int n, q;while (scanf("%d%d", &n, &q) != EOF){mem(ans, 0);mem(lbd, 0);mem(rbd, 0);mem(sum, 0);while (q--){int x = readint();int c = readint() % mod;update(x, c, 1, n, 1);printf("%d\n", ans[1]);}}return 0;}



原创粉丝点击