题意:询问与 u u 相同颜色的联通块的中的最大点权,带修改
这题是稍微加强了一下,思想和 Qtree6 Q t r e e 6 一样,就是维护的信息不同
其实维护颜色相同的联通块基本上是这个套路稳了
这道题维护子树信息的话要开一个 set s e t 维护虚儿子的最大值
推荐先做完 Qtree6 Q t r e e 6 ,这里是 Qtree6 Q t r e e 6 的题解
具体实现和一些细节看代码
#include<bits/stdc++.h>
#define fp(i,a,b) for(int i=a,I=b;i<=I;++i)
#define go(i,u) for(int i=fi[u],v=e[i].to;i;v=e[i=e[i].nx].to)
#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
using namespace std;
char ss[1<<17],*A=ss,*B=ss;
inline char gc(){return A==B&&(B=(A=ss)+fread(ss,1,1<<17,stdin),A==B)?-1:*A++;}
template<class T>inline void sd(T&x){
char c;T y=1;while(c=gc(),(c<48||57<c)&&c!=-1)if(c==45)y=-1;x=c^48;
while(c=gc(),47<c&&c<58)x=(x<<1)+(x<<3)+(c^48);x*=y;
}
char sr[1<<21],z[20];int C=-1,Z;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
template<class T>inline void we(T x){
if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=1e5+5,inf=-1u>>1;
typedef int arr[N];
struct eg{int nx,to;}e[N<<1];
int n,m,ce;arr fi,fa,col;
struct LCT{
int Col,ch[N][2];arr fa,w,val;multiset<int>tp[N];
#define lc(u)(ch[u][0])
#define rc(u)(ch[u][1])
inline bool ir(int u){return lc(fa[u])^u&&rc(fa[u])^u;}
inline bool gf(int u){return rc(fa[u])==u;}
inline void up(int u){w[u]=max(max(tp[u].empty()?-inf:*tp[u].rbegin(),max(w[lc(u)],w[rc(u)])),val[u]);}
inline void rot(int u){
int p=fa[u],k=gf(u);
if(!ir(p))ch[fa[p]][gf(p)]=u;
if(ch[u][!k])fa[ch[u][!k]]=p;
ch[p][k]=ch[u][!k],ch[u][!k]=p;
fa[u]=fa[p],fa[p]=u,up(p);
}
void splay(int u){
for(int f=fa[u];!ir(u);rot(u),f=fa[u])
if(!ir(f))rot(gf(u)==gf(f)?f:u);
up(u);
}
inline void acc(int u){
for(int v=0;u;u=fa[v=u]){
splay(u);
if(ch[u][1])tp[u].insert(w[ch[u][1]]);
if(v)tp[u].erase(tp[u].find(w[v]));
ch[u][1]=v,up(u);
}
}
inline void brt(int u){acc(u),splay(u);}
inline void link(int u,int v){
if(!v)return;
brt(v),splay(u),ch[fa[u]=v][1]=u,up(v);
}
inline void cut(int u,int v){
if(!v)return;
brt(u),fa[lc(u)]=0,lc(u)=0,up(u);
}
inline int Gf(int u){brt(u);while(lc(u))u=lc(u);return u;}
inline int qry(int u){
int p=Gf(u);splay(p);
return col[p]==Col?w[p]:w[ch[p][1]];
}
inline void mdy(int u,int x){brt(u),val[u]=x,up(u);}
}T[2];
inline void add(int u,int v){e[++ce]=eg{fi[u],v},fi[u]=ce;}
void dfs(int u){go(i,u)if(v!=fa[u])T[col[v]].link(v,u),fa[v]=u,dfs(v);}
int main(){
#ifndef ONLINE_JUDGE
file("s");
#endif
sd(n),T[1].Col=1;int u,v;
fp(i,2,n)sd(u),sd(v),add(u,v),add(v,u);
fp(i,1,n)sd(col[i]);fp(i,1,n)sd(T[0].val[i]),T[1].val[i]=T[0].val[i];
fp(c,0,1)fp(i,1,n)T[c].w[i]=T[c].val[i];dfs(1);sd(m);
while(m--){
sd(v),sd(u);int&c=col[u];
if(!v) we(T[c].qry(u));
else if(v==1)T[c].cut(u,fa[u]),c^=1,T[c].link(u,fa[u]);
else sd(v),T[0].mdy(u,v),T[1].mdy(u,v);
}
return Ot(),0;
}