SP16580 QTREE7 - Query on a tree VII
Posted victorique
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SP16580 QTREE7 - Query on a tree VII相关的知识,希望对你有一定的参考价值。
SP16580 QTREE7 - Query on a tree VII
题目描述
题目分析
首先1,2操作就是喜闻乐见的基本操作。可以开两棵LCT,然后分别维护两种颜色。
对于0操作,实际上是查询子树最大值的一个操作。考虑子树和是如何维护的,我们设置了一个(si)数组单独维护。可以考虑设置一棵平衡树来达到(si)数组的作用。具体的可以,嗯,看一看代码。
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+7;
const int inf=2e9+7;
#define lc ch[x][0]
#define rc ch[x][1]
int n,m,col[MAXN],v[MAXN],fa[MAXN];
vector<int> edge[MAXN];
inline int read()
{
int x=0,c=1;
char ch=' ';
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
while(ch=='-')c*=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*c;
}
struct lct{
int ch[MAXN][2],mx[MAXN],f[MAXN],r[MAXN];
multiset<int> s[MAXN];
lct(){mx[0]=-inf;}
inline bool nroot(int x){return ch[f[x]][0]==x||ch[f[x]][1]==x;}
inline void pushup(int x){
mx[x]=max(v[x],max(mx[lc],mx[rc]));
if(!s[x].empty())
mx[x]=max(mx[x],-*s[x].begin());
}
inline void rotate(int x){
int y=f[x],z=f[y],kind=ch[y][1]==x,w=ch[x][!kind];
if(nroot(y)) ch[z][ch[z][1]==y]=x;ch[x][!kind]=y;ch[y][kind]=w;
if(w) f[w]=y;f[f[y]=x]=z;
pushup(y);
}
inline void splay(int x){
int y,z;
while(nroot(x)){
y=f[x],z=f[y];
if(nroot(y)) rotate((ch[y][0]==x)^(ch[z][0]==y)?x:y);
rotate(x);
}
pushup(x);
}
inline void access(int x){
for(int y=0;x;x=f[y=x]){
splay(x);
if(rc) s[x].insert(-mx[rc]);
if((rc=y)) s[x].erase(s[x].find(-mx[y]));
pushup(x);
}
}
inline int findroot(int x){
access(x);splay(x);
while(lc) x=lc;
splay(x);
return x;
}
inline void link(int x){
splay(x);
int y=f[x]=fa[x];
access(y);splay(y);
ch[y][1]=x;pushup(y);
}
inline void cut(int x){
access(x);splay(x);
lc=f[lc]=0;
pushup(x);
}
}LCT[2];
inline void dfs(int u,int ff)
{
fa[u]=ff;
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i];
if(v==ff) continue;
dfs(v,u);
}
LCT[col[u]].link(u);
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("my.out","w",stdout);
n=read();
for(int i=1;i<n;i++){
int x=read(),y=read();
edge[x].push_back(y);
edge[y].push_back(x);
}
for(int i=1;i<=n;i++) col[i]=read();
for(int i=1;i<=n;i++) v[i]=read();
fa[1]=n+1;
dfs(1,n+1);
m=read();
for(int i=1;i<=m;i++){
int fl=read();
if(fl==0){
int u=read();
int x=LCT[col[u]].findroot(u);
printf("%d
", LCT[col[u]].mx[LCT[col[u]].rc]);
} else if(fl==1){
int u=read();
LCT[col[u]].cut(u);
col[u]^=1;
LCT[col[u]].link(u);
} else {
int u=read();
LCT[col[u]].access(u);LCT[col[u]].splay(u);v[u]=read();
LCT[col[u]].pushup(u);
// LCT[0].access(u);LCT[0].splay(u);LCT[0].pushup(u);
// LCT[1].access(u);LCT[1].splay(u);LCT[1].pushup(u);
}
}
}
以上是关于SP16580 QTREE7 - Query on a tree VII的主要内容,如果未能解决你的问题,请参考以下文章
题解 SP375 QTREE - Query on a tree