#include <cstdio>
#include <cstring>
#include <algorithm>
#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<<j) <= tot;j++)
{
for (i = 0;i + (1<<j) <= tot;i++)
{
if (j == 0) dp[i][j] = i;
else
{
if (dep[dp[i][j - 1]] < dep[dp[i + (1<<(j - 1))][j - 1]]) dp[i][j] = dp[i][j - 1];
else dp[i][j] = dp[i + (1<<(j - 1))][j - 1];
}
}
}
}
int RMQ(int p1, int p2)
{
int k = 0;
while ((1<<k) <= p2 - p1 + 1) k++;k--;
if (dep[dp[p1][k]] < dep[dp[p2 - (1<<k) + 1][k]])
return t[dp[p1][k]];
else return t[dp[p2 - (1<<k) + 1][k]];
}
int lac(int v1, int v2)
{
if (pos[v1] < pos[v2]) return RMQ(pos[v1], pos[v2]);
else return RMQ(pos[v2], pos[v1]);
}
int F[N];
void dfs(int u, int fa, int dfn)
{
int i;
if (!vi[u])
{
vi[u] = 1, lq[u] = ++id, F[u] = fa;
T[u] = update(0, M-1, w[u-1], 1, T[fa]);
pos[u] = tot;//第一次出现的时间
}
dep[tot] = dfn;//深度序列;
t[tot++] = u;//欧拉序列;
for (i = head[u];~i;i = e[i].ne)
{
if (vi[e[i].v]) continue;
dfs(e[i].v, u, dfn + 1);
dep[tot] = dfn;
t[tot++] = u;
}
rq[u] = id+1;
return;
}
int S[N], Ro[N*30], Lo[N*30];
int lb(int k){return k&(-k);}
void adds(int i, int k, int val, int n)
{
while (i <= n)
{
S[i] = update(0, M-1, k, val, S[i]);
i += lb(i);
}
}
void get(int ro[], int x)
{
ro[++ro[0]] = T[x];
x = lq[x];
while (x > 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;
}
}
}
}
BZOJ 1146: [CTSC2008]网络管理Network 【树上带修改主席树】
最新推荐文章于 2019-10-07 16:21:30 发布