被数据结构题艹哭QAQ 果然我数据结构还是太弱了
如果你做过我blog上一篇的那道COT 那就好办很多了(没做的去做做?
虽说我并不是先做COT的 而是先做这题 (捂脸
这题在COT的基础上 考虑到修改一个点只会影响其子树内的点
那我们就可以想到用dfs序来搞 方便修改
所以用树状数组维护主席树 查询的时候就用上一题相同的套路 把所有要加减的主席树弄出来,然后一起在主席树上走就好
对了 为了主席树快一点 小一点 离散化一下是极好的
不懂的话 我觉得我的代码还是挺能看的 LCA用了O(n)那种….
然后我愉快地去抄了个网上最短的代码
诶 为啥我的代码 连这种题都没有100行
#include<bits/stdc++.h>
#define pa pair<int,int>
using namespace std;
const int N=8e4+2;
char B[1<<14],*S=B,*T=B;
#define gc (S==T&&(T=(S=B)+fread(B,1,1<<14,stdin),S==T)?-1:*S++)
inline int read(){
int x=0,f=1; char ch=gc;
while(ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=gc;}
while(ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=gc;}
return x*f;
}
struct ED{int y,nex;}e[N<<1]; int len,fir[N];
void ins(int x,int y){
e[++len]=(ED){y,fir[x]},fir[x]=len;
}
int z[N<<1],fa[N],p[N],a[N],K[N],u[N],v[N],zl,tot,id,in[N],out[N];
int n,rt[N],lc[N*80],rc[N*80],s[N*80],L[N<<2],R[N<<2],sl,sr,c[N],lca[N];
bool vis[N];
vector<pa >q[N];
void upd(int &x,int l,int r,int k,int u){
lc[++tot]=lc[x],rc[tot]=rc[x],s[tot]=s[x]+u,x=tot;
if(l==r)return;
int mid=l+r>>1;
if(k<=mid)upd(lc[x],l,mid,k,u); else upd(rc[x],mid+1,r,k,u);
}
int query(int l,int r,int k){
if(l==r)return l;
int i,s1=0,s2=0,mid=l+r>>1;
for(i=1;i<=sr;++i) s1+=s[rc[R[i]]],s2+=s[R[i]];
for(i=1;i<=sl;++i) s1-=s[rc[L[i]]],s2-=s[L[i]];
if(s2<k) return -1;
if(k<=s1){
for(i=1;i<=sl;++i)L[i]=rc[L[i]];
for(i=1;i<=sr;++i)R[i]=rc[R[i]];
return query(mid+1,r,k);
}
for(i=1;i<=sl;++i)L[i]=lc[L[i]];
for(i=1;i<=sr;++i)R[i]=lc[R[i]];
return query(l,mid,k-s1);
}
void get(int x,int k){
if(k){R[++sr]=rt[x]; for(x=in[x];x;x-=x&-x)R[++sr]=c[x];}
else {L[++sl]=rt[x]; for(x=in[x];x;x-=x&-x)L[++sl]=c[x];}
}
void change(int x,int k,int u){
for(;x<=n;x+=x&-x) upd(c[x],1,zl,k,u);
}
int Find(int x){return x==p[x]?x:p[x]=Find(p[x]);}
void dfs(int x){
p[x]=x,rt[x]=rt[fa[x]],upd(rt[x],1,zl,a[x],1);
in[x]=++id;
for(int k=fir[x];k;k=e[k].nex) if(fa[x]!=e[k].y){
fa[e[k].y]=x; dfs(e[k].y); p[e[k].y]=x;
} out[x]=id,vis[x]=1;
int t=q[x].size();
for(int i=0;i<t;++i) if(vis[q[x][i].first]) lca[q[x][i].second]=Find(q[x][i].first);
}
int main(){
n=read(); int m=read(),x,y,i; zl=0;
for(i=1;i<=n;++i) a[i]=z[++zl]=read();
for(i=1;i<n;++i) x=read(),y=read(),ins(x,y),ins(y,x);
for(i=1;i<=m;++i){
K[i]=read(),u[i]=read(),v[i]=read();
if(K[i])
q[u[i]].push_back(pa(v[i],i)),
q[v[i]].push_back(pa(u[i],i));
else z[++zl]=v[i];
}
sort(z+1,z+1+zl); zl=unique(z+1,z+1+zl)-z-1;
for(i=1;i<=n;++i) a[i]=lower_bound(z+1,z+1+zl,a[i])-z;
dfs(n+1>>1);
for(i=1;i<=m;++i)
if(K[i]){
sl=sr=0;
get(u[i],1),get(v[i],1),get(lca[i],0),get(fa[lca[i]],0);
int o=query(1,zl,K[i]);
if(o<=0) puts("invalid request!");
else printf("%d\n",z[o]);
}
else{
x=u[i],y=lower_bound(z+1,z+1+zl,v[i])-z;
change(in[x],a[x],-1),change(out[x]+1,a[x],1);
change(in[x],y,1),change(out[x]+1,a[x]=y,-1);
}
return 0;
}