【BZOJ3155】Preprefix sum【树状数组】

【题目链接】

∑((x - i + 1) * ai) = ∑((n - i + 1) * ai) - (n - x) * ∑ai

/* Pigonometry */
#include <cstdio>
#include <algorithm>

using namespace std;

typedef long long LL;

const int maxn = 100005;

int n, m, num[maxn];
LL tr[maxn][2];

inline int iread() {
	int f = 1, x = 0; char ch = getchar();
	for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return f * x;
}

inline void add(int k, int x, LL c) {
	for(; x <= n; x += x & -x) tr[x][k] += c;
}

inline LL sum(int k, int x) {
	LL res = 0;
	for(; x; x -= x & -x) res += tr[x][k];
	return res;
}

int main() {
	n = iread(); m = iread();
	for(int i = 1; i <= n; i++) {
		num[i] = iread();
		add(0, i, num[i]);
		add(1, i, (LL)(n - i + 1) * num[i]);
	}

	while(m--) {
		char ch = getchar(); for(; ch != 'Q' & ch != 'M'; ch = getchar());
		if(ch == 'M') {
			int pos = iread(), c = iread();
			add(0, pos, c - num[pos]);
			add(1, pos, (LL)(n - pos + 1) * (c - num[pos]));
			num[pos] = c;
		}
		else if(ch == 'Q') {
			int pos = iread();
			printf("%lld\n", sum(1, pos) - (n - pos) * sum(0, pos));
		}
	}
	return 0;
}


你可能感兴趣的:(树状数组)