BZOJ 2016十連測 D3T3序列
阿新 • • 發佈:2018-11-03
主席樹
#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); } }