题意
一棵树,每个点初始有个点权和颜色(输入会给你)
0 u :询问所有 u,v 路径上的最大点权,要满足 u,v 路径上所有点的颜色都相同 .
1 u:反转 u 的颜色
2 u w:把 u的点权改成 w
colori∈[0,1],wi∈[−109,109],n,m≤105
c
o
l
o
r
i
∈
[
0
,
1
]
,
w
i
∈
[
−
10
9
,
10
9
]
,
n
,
m
≤
10
5
题解
跟Qtree6差不多。对于u,v路径上的点权,用multiset维护一下即可。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<set>
using namespace std;
const int N=1e5+50,inf=1e9+10;
int n,m,col[N],fa[N];
int head[N],to[N<<1],nxt[N<<1],tot;
inline int rd()
{
char ch=getchar();int x=0,f=1;
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
return x*f;
}
inline void lkk(int u,int v)
{to[++tot]=v;nxt[tot]=head[u];head[u]=tot;}
struct T{
int ch[N][2],mx[N],v[N],f[N];
multiset<int>st[N];
T(){for(int i=0;i<N;++i) mx[i]=v[i]=-inf;}
bool isrt(int x){return (ch[f[x]][0]!=x) && (ch[f[x]][1]!=x);}
void update(int x){
mx[x]=max(v[x],max(mx[ch[x][0]],mx[ch[x][1]]));
if(!st[x].empty()) mx[x]=max(mx[x],*st[x].rbegin());
}
void rotate(int x){
int y=f[x],z=f[y],gs=ch[y][1]==x;f[x]=z;
if(!isrt(y)) ch[z][ch[z][1]==y]=x;
ch[y][gs]=ch[x][gs^1];f[ch[x][gs^1]]=y;
ch[x][gs^1]=y;f[y]=x;update(y);
}
void splay(int x){
int y,z;
while(!isrt(x)){
y=f[x];z=f[y];
if(!isrt(y)) (ch[z][1]==y)^(ch[y][1]==x)?rotate(x):rotate(y);
rotate(x);
}
update(x);
}
void access(int x){
for(int y=0;x;x=f[x]){
splay(x);
if(ch[x][1]) st[x].insert(mx[ch[x][1]]);
if(y) st[x].erase(st[x].find(mx[y]));ch[x][1]=y;
update(x);
y=x;
}
}
int fdrt(int x){
access(x);splay(x);
for(;ch[x][0];x=ch[x][0]);
splay(x);
return x;
}
void lk(int x){
splay(x);
f[x]=fa[x];
access(f[x]);splay(f[x]);
ch[f[x]][1]=x;update(f[x]);
}
void cut(int x){
access(x);splay(x);
f[ch[x][0]]=0;ch[x][0]=0;
update(x);
}
int query(int x){
x=fdrt(x);
return mx[ch[x][1]];
}
}lct[2];
inline void dfs(int x)
{
for(int j,i=head[x];i;i=nxt[i]){
j=to[i];
if(j!=fa[x]){
fa[j]=x;dfs(j);lct[col[j]].lk(j);
}
}
}
inline void change(int x,int w)
{
lct[0].access(x);lct[0].splay(x);lct[0].v[x]=w;lct[0].update(x);
lct[1].access(x);lct[1].splay(x);lct[1].v[x]=w;lct[1].update(x);
}
int main(){
int i,j,x,y,op;
n=rd();
for(i=1;i<n;++i){x=rd();y=rd();lkk(x,y);lkk(y,x);}
for(i=1;i<=n;++i) col[i]=rd();
for(i=1;i<=n;++i){lct[0].v[i]=lct[0].mx[i]=lct[1].v[i]=lct[1].mx[i]=rd();}
dfs(1);fa[1]=n+1;lct[col[1]].lk(1);
m=rd();
while(m--){
op=rd();x=rd();
if(!op) printf("%d\n",lct[col[x]].query(x));
else if(op==1) {lct[col[x]].cut(x);lct[col[x]^=1].lk(x);}
else change(x,rd());
}
}