1. 程式人生 > >hihocoder-1116 : 計算 (線段樹區間合併)

hihocoder-1116 : 計算 (線段樹區間合併)

描述

現在有一個有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

#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);
	else
		update(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;
}