BZOJ 1146: [CTSC2008]网络管理Network 【树上带修改主席树】

#include 
#include 
#include 
#define N 100005
using namespace std;

int a[N], b[N], M, T[N], st, w[N], A[N], B[N], C[N];

struct Tr
{
    int c, ls, rs;
}tr[8000010];

int hash(int k)
{
    return lower_bound(b, b+M, k)-b;
}

int build(int l, int r)
{
    int nr = st++, mid = l+r>>1;
    tr[nr].c = 0;
    if (l < r)
    {
        tr[nr].ls = build(l, mid);
        tr[nr].rs = build(mid+1, r);
    }
    return nr;
}

int update(int l, int r, int pos, int val, int root)
{
    int nr = st++, mid = l+r>>1;
    tr[nr].c = tr[root].c+val;
    if (l < r)
    {
        if (pos <= mid) tr[nr].ls = update(l, mid, pos, val, tr[root].ls), tr[nr].rs = tr[root].rs;
        else tr[nr].rs = update(mid+1, r, pos, val, tr[root].rs), tr[nr].ls = tr[root].ls;
    }
    return nr;
}

int tot, dep[N*4], pos[N], t[N*4], dp[N*4][20], size, head[N], id;
int lq[N], rq[N];
bool vi[N];

struct E
{
    int v, ne;
    E(){}
    E(int _v, int _ne):v(_v), ne(_ne){}
}e[N*2];

void init()
{
     memset(vi, 0, sizeof(vi));
     memset(head, -1, sizeof(head));
     size = tot = st = id = 0;
}

void add(int u, int v)
{
     e[size] = E(v, head[u]);
     head[u] = size++;
}

void DP()
{
     int i, j;
     memset(dp, 0, sizeof(dp));
     for (j = 0;(1< 0) {ro[++ro[0]] = S[x]; x -= lb(x);}
}

void go(int ro[], int p)
{
    int i;
    for (i = 1;i <= ro[0];i++)
    {
        if (!p) ro[i] = tr[ro[i]].rs;
        else ro[i] = tr[ro[i]].ls;
    }
}

int query(int l, int r, int k)
{
    int i, sum = 0, mid = l+r>>1, tt = 0;
    if (l == r) return l;
    for (i = 1;i <= Ro[0];i++) sum += tr[tr[Ro[i]].rs].c, tt += tr[Ro[i]].c;
    for (i = 1;i <= Lo[0];i++) sum -= tr[tr[Lo[i]].rs].c, tt -= tr[Lo[i]].c;
    if (tt < k) return -1;
    if (sum >= k)
    {
        go(Ro, 0), go(Lo, 0);
        return query(mid+1, r, k);
    }
    else
    {
        go(Ro, 1), go(Lo, 1);
        return query(l, mid, k-sum);
    }
}

void cal(int l, int r, int k)
{
    int fa = lac(l, r);
    Ro[0] = Lo[0] = 0;
    get(Ro, l), get(Ro, r), get(Lo, fa), get(Lo, F[fa]);
    int re = query(0, M-1, k);
    if (re < 0) puts("invalid request!");
    else printf("%d\n", b[re]);
}

int main()
{
    int i, n, m, u, v, k;
    while (~scanf("%d%d", &n, &m))
    {
        init();M = 0;
        for (i = 0;i < n;i++) scanf("%d", &a[i]), b[M++] = a[i];
        for (i = 1;i < n;i++)
        {
            scanf("%d%d", &u, &v);
            add(u, v), add(v, u);
        }
        for (i = 0;i < m;i++)
        {
            scanf("%d%d%d", &A[i], &B[i], &C[i]);
            if (!A[i]) b[M++] = C[i];
        }
        memset(S, 0, sizeof(S));
        sort(b, b+M);
        M = unique(b, b+M)-b;
        T[0] = build(0, M-1);
        for (i = 0;i < n;i++) w[i] = hash(a[i]);
        dfs(1, 0, 0);
        DP();
        for (i = 0;i < m;i++)
        {
            k = A[i], u = B[i], v = C[i];
            if (k > 0) cal(u, v, k);
            else
            {
                v = hash(v);
                adds(lq[u], w[u-1], -1, n), adds(rq[u], w[u-1], 1, n);
                adds(lq[u], v, 1, n), adds(rq[u], v, -1, n);
                w[u-1] = v;
            }
        }
    }
}

你可能感兴趣的:(主席树)