cychester

BZOJ 2016十连测 D3T3序列

主席树

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define rd read()
using namespace std;

const int N = 1e5 + 5;

int ls[N], tot, n, m, q;
int a[N], ans;
vector<int> ad[N], reduce[N];

struct que {
	int l, r, x;
}b[N];

int read() {
	int X = 0, p = 1; char c = getchar();
	for (; c > '9' || c < '0'; c = getchar())
		if (c == '-') p = -1;
	for (; c >= '0' && c <= '9'; c = getchar())
		X = X * 10 + c - '0';
	return X * p;
}

namespace SegT {
	int cnt, root[N];
	struct node {
		int sum, lson, rson;
	}p[N * 50];
#define lc(x) p[x].lson
#define rc(x) p[x].rson
#define sum(x) p[x].sum
#define mid ((l + r) >> 1)

	void modify(int &x, int now, int pos, int d, int l, int r) {
		x = ++cnt;
		sum(x) = sum(now) + d;
		lc(x) = lc(now);
		rc(x) = rc(now);
		if (l == r) return;
		if (pos <= mid) modify(lc(x), lc(now), pos, d, l, mid);
		else modify(rc(x), rc(now), pos, d, mid + 1, r);
	}

	int query(int x, int pos, int l, int r) {
		if (!x) return 0;
		if (r <= pos) return sum(x);
		int res = 0;
		if (mid <= pos) 
			return query(lc(x), pos, l, mid) + query(rc(x), pos, mid + 1, r);
		else 
			return query(lc(x), pos, l, mid);
	}
}using namespace SegT;

int main()
{
	n = rd; m = rd; q = rd;
	for (int i = 1; i <= n; ++i) a[i] = rd;
	for (int i = 1; i <= m; ++i)
		b[i].l = rd, b[i].r = rd, b[i].x = rd, ls[++tot] = b[i].x;
	sort(ls + 1, ls + 1 + tot);
	tot = unique(ls + 1, ls + 1 + tot) - ls - 1;
	for (int i = 1; i <= m; ++i) {
		int tmp = lower_bound(ls + 1, ls + 1 + tot, b[i].x) - ls;
		ad[tmp].push_back(b[i].l);
		if (b[i].r < n) reduce[tmp].push_back(b[i].r + 1);
	}
	for (int i = 1; i <= tot; ++i) {
		root[i] = root[i - 1];
		for (int j = 0, up = ad[i].size(); j < up; ++j)
			modify(root[i], root[i], ad[i][j], 1, 1, n);
		for (int j = 0, up = reduce[i].size(); j < up; ++j)
			modify(root[i], root[i], reduce[i][j], -1, 1, n);
	}
	for (int i = 1; i <= n; ++i) {
		int tmp = upper_bound(ls + 1, ls + 1 + tot, a[i]) - 1 - ls;
		ans += query(root[tmp], i, 1, n);
	}
	printf("%d\n", ans);
	for (int i = 1; i <= q; ++i) {
		int u = rd ^ ans, v = rd ^ ans;
		int tmp = upper_bound(ls + 1, ls + 1 + tot, a[u]) - 1 - ls;
		ans -= query(root[tmp], u, 1, n);
		a[u] = v;
		tmp = upper_bound(ls + 1, ls + 1 + tot, a[u]) - 1 - ls;
		ans += query(root[tmp], u, 1, n);
		printf("%d\n", ans);
	}
}

posted on 2018-11-03 11:09  cychester  阅读(158)  评论(1编辑  收藏  举报

导航