#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 80001
int v[N<<1],en,first[N],next[N<<1];
void AddEdge(int U,int V)
{
v[++en]=V;
next[en]=first[U];
first[U]=en;
}
struct Point{int p,v;}t[86000];
bool operator < (Point a,Point b){return a.v<b.v;}
int n,m,ma[86000],a[86000],zy,b[86000];
int eq,ec,blo,sz,siz[N],top[N],fa[N],dep[N],num[N];
void dfs(int U)
{
for(int i=first[U];i;i=next[i])
if(v[i]!=fa[U])
{
fa[v[i]]=U;
dep[v[i]]=dep[U]+1;
if(siz[top[U]]<sz)
{
++siz[top[U]];
top[v[i]]=top[U];
}
dfs(v[i]);
}
}
void df2(int U)
{
num[U]=blo;
for(int i=first[U];i;i=next[i])
if(v[i]!=fa[U]&&top[v[i]]==top[U])
df2(v[i]);
}
int lca(int U,int V)
{
while(U!=V)
{
if(top[U]!=top[V])
{
if(dep[top[U]]<dep[top[V]])
swap(U,V);
U=fa[top[U]];
}
else
{
if(dep[U]<dep[V])
swap(U,V);
U=fa[U];
}
}
return U;
}
struct UPT{int x,y,z;}CH[N];
struct ASK{int l,r,k,p,t;}Q[N];
bool operator < (const ASK &a,const ASK &b)
{
if(num[a.l]==num[b.l])
{
if(num[a.r]==num[b.r])
return a.t<b.t;
return num[a.r]<num[b.r];
}
return num[a.l]<num[b.l];
}
int nu2[86000],r[300],sumv[300],bl2=1,T[86000];
void makeblock()
{
int sz=sqrt(zy); if(!sz) sz=0;
for(;bl2*sz<zy;++bl2)
{
r[bl2]=bl2*sz;
for(int i=r[bl2-1]+1;i<=r[bl2];++i)
nu2[i]=bl2;
}
r[bl2]=zy;
for(int i=r[bl2-1]+1;i<=r[bl2];++i)
nu2[i]=bl2;
}
void Update(int x,int op){T[x]+=op; sumv[nu2[x]]+=op;}
bool vis[N];
void Work(int U,int V,int LCA)
{
while(U!=LCA)
{
vis[U]^=1;
Update(a[U],vis[U]?1:-1);
U=fa[U];
}
while(V!=LCA)
{
vis[V]^=1;
Update(a[V],vis[V]?1:-1);
V=fa[V];
}
}
int Kth(int K)
{
int cnt=0;
for(int i=bl2;i;--i)
{
cnt+=sumv[i];
if(cnt>=K)
{
cnt-=sumv[i];
for(int j=r[i];;--j)
{
cnt+=T[j];
if(cnt>=K)
return ma[j];
}
}
}
return -1;
}
int Ks[N],anss[N];
int main()
{
int x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
{
scanf("%d",&t[i].v);
t[i].p=i;
}
for(int i=1;i<n;++i)
{
scanf("%d%d",&x,&y);
AddEdge(x,y);
AddEdge(y,x);
}
for(int i=1;i<=n;++i)
{
top[i]=i;
siz[i]=1;
}
sz=(int)pow((double)n,2.0/3.0);
dfs(1);
for(int i=1;i<=n;++i)
if(top[i]==i)
{
++blo;
df2(i);
}
en=n;
for(int i=1;i<=m;++i)
{
scanf("%d",&Ks[i]);
if(!Ks[i])
{
++ec; ++en;
scanf("%d%d",&CH[ec].x,&t[en].v);
t[en].p=en;
}
else
{
++eq;
Q[eq].k=Ks[i];
scanf("%d%d",&Q[eq].l,&Q[eq].r);
Q[eq].t=ec; Q[eq].p=eq;
}
}
sort(t+1,t+en+1);
ma[a[t[1].p]=++zy]=t[1].v;
for(int i=2;i<=en;++i)
{
if(t[i].v!=t[i-1].v) ++zy;
ma[a[t[i].p]=zy]=t[i].v;
}
makeblock();
memcpy(b,a,sizeof(int)*(n+1));
en=n; ec=0;
for(int i=1;i<=m;++i)
if(!Ks[i])
{
++en; ++ec;
CH[ec].y=a[en];
CH[ec].z=b[CH[ec].x];
b[CH[ec].x]=a[en];
}
sort(Q+1,Q+eq+1);
for(int i=1;i<=Q[1].t;++i)
a[CH[i].x]=CH[i].y;
int LCA=lca(Q[1].l,Q[1].r);
Work(Q[1].l,Q[1].r,LCA);
Update(a[LCA],1);
anss[Q[1].p]=Kth(Q[1].k);
Update(a[LCA],-1);
for(int i=2;i<=eq;++i)
{
if(Q[i-1].t<Q[i].t) for(int j=Q[i-1].t+1;j<=Q[i].t;++j)
{
if(vis[CH[j].x])
{
Update(CH[j].y,1);
Update(a[CH[j].x],-1);
}
a[CH[j].x]=CH[j].y;
}
else for(int j=Q[i-1].t;j>Q[i].t;--j)
{
if(vis[CH[j].x])
{
Update(CH[j].z,1);
Update(a[CH[j].x],-1);
}
a[CH[j].x]=CH[j].z;
}
Work(Q[i-1].l,Q[i].l,lca(Q[i-1].l,Q[i].l));
Work(Q[i-1].r,Q[i].r,lca(Q[i-1].r,Q[i].r));
LCA=lca(Q[i].l,Q[i].r);
Update(a[LCA],1);
anss[Q[i].p]=Kth(Q[i].k);
Update(a[LCA],-1);
}
for(int i=1;i<=eq;++i)
if(anss[i]!=-1)
printf("%d\n",anss[i]);
else
puts("invalid request!");
return 0;
}
转载于:https://www.cnblogs.com/autsky-jadek/p/4428522.html