求助主席树,样例过不去
查看原帖
求助主席树,样例过不去
394729
Weight_of_the_Soul楼主2022/8/26 13:49
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;

int rd() {
    int x = 0, w = 1;
    char c = getchar();

    while(c < '0' || c > '9') {
        if(c == '-') w = -1;
        c = getchar();
    }

    while(c >= '0' && c <= '9') {
        x = x * 10 + (c - '0');
        c = getchar();
    }

    return x * w;
}

const int N = 1e5 + 5;

int n;
int top;
int a[N], b[N], root[N];

struct Tree {
    int ls, rs;
    int dat;

    #define ls(x) t[x].ls
    #define rs(x) t[x].rs
    #define dat(x) t[x].dat

}t[N << 2];

struct Graph {
    int v, nxt;
}e[N << 1];

int lk[N], ltp;

void ins(int u, int v) {
    
    e[++ltp] = (Graph) {v, lk[u]};
    lk[u] = ltp;
}

int las = 0;

int dfn[N], siz[N], son[N], fa[N], ttop[N], dep[N], rk[N];

void dfs1(int u) {
    siz[u] = 1;
    son[u] = -1;
    for(int i = lk[u]; i; i = e[i].nxt) {
        int v = e[i].v;
        if(!dep[v]) {
            dep[v] = dep[u] + 1;
            fa[v] = u;
            dfs1(v);
            siz[u] += siz[v];
            if(son[u] == -1 || siz[v] > siz[son[u]])
                son[u] = v;
        }
    }
}

int num;
int c[N];

void dfs2(int u, int tt) {
    dfn[u] = ++num;
    rk[num] = u;
    ttop[u] = tt;

    if(son[u] == -1) return ;

    dfs2(son[u], tt);
    for(int i = lk[u]; i; i = e[i].nxt) {
        int v = e[i].v;
        if(v != fa[u] && v != son[u])
            dfs2(v, v);
    }
}

int sum;

int build(int l, int r) {
    int p = ++top;
    if(l == r) return p;
    int mid = (r - l) / 2 + l;

    ls(p) = build(l, mid);
    rs(p) = build(mid + 1, r);
    return p;
}

int change(int now, int l, int r, int x) {
    int p = ++top;
    t[p] = t[now];

    if(l == r) {
        ++dat(p);
        return p;
    }

    int mid = (r - l) / 2 + l;
    if(x <= mid) ls(p) = change(ls(p), l, mid, x);
    if(x > mid) rs(p) = change(rs(p), mid + 1, r, x);
    dat(p) = dat(rs(p)) + dat(ls(p));
    return p;
}

int ask(int a1, int a2, int a3, int a4, int l, int r, int k) {
    if(l == r) return l;

    int lcnt = dat(a1) + dat(a2) - dat(a3) - dat(a4);
    int mid = (r - l) / 2 + l;
    if(k <= lcnt) return ask(ls(a1), ls(a2), ls(a3), ls(a4), l, mid, k);
    else return ask(rs(a1), rs(a2), rs(a3), rs(a4), mid + 1, r, k - lcnt);
}

void dfs(int u) {
    root[u] = change(root[fa[u]], 1, sum, c[u]);
    for(int i = lk[u]; i; i = e[i].nxt) {
        int v = e[i].v;
        if(v != fa[u])
            dfs(v);
    }
}

int m;

int get_lca(int u, int v) {
    while(ttop[u] != ttop[v]) {
        if(dep[ttop[u]] > dep[ttop[v]]) u = fa[ttop[u]];
        else v = fa[ttop[v]];
    }

    return dep[u] < dep[v] ? u : v;
}

int main() {
    n = rd(), m = rd();
    for(int i = 1; i <= n; ++i) a[i] = rd(), b[i] = a[i];

    sort(a + 1, a + 1 + n);
    sum = unique(a + 1, a + 1 + n) - a - 1;
    root[0] = build(1, sum);
    for(int i = 1; i <= n; ++i)
        c[i] = lower_bound(a + 1, a + 1 + num, b[i]) - a;

    for(int i = 1; i < n; ++i) {
        int u = rd(), v = rd();
        ins(u, v);
        ins(v, u);
    }

    dep[1] = 1;
    dfs1(1);
    dfs2(1, 1);
    dfs(1);

    while(m--) {
        int u = rd(), v = rd(), k = rd();
        u ^= las;
        int lca = get_lca(u, v);

        int ans = a[ask(u, v, lca, fa[lca], 1, num, k)];
        las = ans;
        printf("%d\n", ans);
    }
    return 0;
}
2022/8/26 13:49
加载中...