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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1059752567/article/details/78140044

描述

现在有一个有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;
}



猜你喜欢

转载自blog.csdn.net/qq1059752567/article/details/78140044
今日推荐