1. 程式人生 > >BZOJ 2016十連測 D3T3序列

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);
    }
}