SP16580 QTREE7 - Query on a tree VII
Description
一棵树,每个点初始有个点权和颜色(0/1) 0 u :询问所有u,v 路径上的最大点权,要满足u,v 路径上所有点的颜色都相同 1 u :反转u 的颜色 2 u w :把u 的点权改成w
Solution
对于每一种颜色,我们开一个 \(LCT\) 来维护
首先为了使得 \(LCT\) 维护的黑树连通,难免会有白点,但是最多只会有一个,因为一旦不连通了就没有必要维护了,对于白树也是同理
对于每一个 \(LCT\) 的节点,只需要维护一个 \(splay\) 中的子树 \(max\) 和虚子树的 \(max\) 就行了,和平时的 \(LCT\) 维护虚子树的方法相同,只需要把虚子树的答案当作这个点的权值就好了,唯一不同的是,这个题是维护 \(max\),不能支持加减操作,所以用一个 \(set\) 或 堆来维护就行了
一个细节:
对于一个连通块,可能根节点是不同色点,对于询问那么就需要加一个特判:
如果是根节点不同色的,答案就是右子树的答案
否则就是根节点的答案
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int pa[N],n,Q,head[N],nxt[N*2],to[N*2],num=0,c[N];
struct lxt{
int fa[N],ch[N][2],v[N],w[N];
multiset<int>S[N];
inline bool isrt(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
inline void upd(int x){
v[x]=w[x];
if(!S[x].empty())v[x]=max(v[x],*--S[x].end());
if(ch[x][0])v[x]=max(v[x],v[ch[x][0]]);
if(ch[x][1])v[x]=max(v[x],v[ch[x][1]]);
}
inline void rotate(int x){
int y=fa[x];bool t=(ch[y][1]==x);
ch[y][t]=ch[x][!t];
fa[ch[y][t]]=y;
ch[x][!t]=y;
fa[x]=fa[y];
if(!isrt(y))ch[fa[y]][ch[fa[y]][1]==y]=x;
fa[y]=x;upd(y);upd(x);
}
inline void splay(int x){
while(!isrt(x)){
int y=fa[x],p=fa[y];
if(isrt(y))rotate(x);
else if((ch[p][0]==y)==(ch[y][0]==x))rotate(y),rotate(x);
else rotate(x),rotate(x);
}
}
inline void access(int x){
int y=0;
while(x){
splay(x);
if(ch[x][1])S[x].insert(v[ch[x][1]]);
if(y)S[x].erase(S[x].find(v[y]));
ch[x][1]=y;upd(x);x=fa[y=x];
}
}
inline int query(int x){
int co=c[x];
access(x);splay(x);
while(ch[x][0])x=ch[x][0];
splay(x);
return co==c[x]?v[x]:v[ch[x][1]];
}
inline void cut(int x){
if(!pa[x])return ;
access(x);splay(x);fa[ch[x][0]]=0;ch[x][0]=0;upd(x);
}
inline void link(int x){
if(!pa[x])return ;
access(pa[x]);splay(pa[x]);splay(x);
ch[pa[x]][1]=x;fa[x]=pa[x];upd(pa[x]);
}
}tr[2];
inline void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;}
inline void build(int x,int last){
for(int u,i=head[x];i;i=nxt[i]){
if((u=to[i])==last)continue;
build(u,x);pa[u]=x;
tr[c[u]].fa[u]=x;tr[c[u]].S[x].insert(tr[c[u]].v[u]);
}tr[0].upd(x);tr[1].upd(x);
}
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
cin>>n;
int x,y,op;
for(int i=1;i<n;i++){
scanf("%d%d",&x,&y);
link(x,y);link(y,x);
}
for(int i=1;i<=n;i++)scanf("%d",&c[i]);
for(int i=1;i<=n;i++)scanf("%d",&tr[0].w[i]),tr[1].w[i]=tr[0].w[i];
build(1,0);
cin>>Q;
while(Q--){
scanf("%d%d",&op,&x);
if(op==0)printf("%d\n",tr[c[x]].query(x));
else if(op==1){
tr[c[x]].cut(x);tr[c[x]^1].link(x);
c[x]^=1;
}
else {
scanf("%d",&y);
tr[0].access(x);tr[0].splay(x);
tr[1].access(x);tr[1].splay(x);
tr[0].w[x]=tr[1].w[x]=y;
tr[0].upd(x);tr[1].upd(x);
}
}
return 0;
}
SP16580 QTREE7 - Query on a tree VII的更多相关文章
- 洛谷SP16580 QTREE7 - Query on a tree VII(LCT,multiset)
洛谷题目传送门 思路分析 维护子树最值还是第一次写QwQ 因为子树的最值会变化,所以不能简单地把最值记下来,还要维护一个平衡树,把每个子树的最大值扔进去,来资磁插入.删除和查询最值. 然后我就懒得手写 ...
- SP16580 QTREE7 - Query on a tree VII(LCT)
题意翻译 一棵树,每个点初始有个点权和颜色(输入会给你) 0 u:询问所有u,v路径上的最大点权,要满足u,v路径上所有点颜色相同 1 u:反转u的颜色 2 u w:把u的点权改成w 题解 Qtree ...
- bzoj3639: Query on a tree VII
Description You are given a tree (an acyclic undirected connected graph) with n nodes. The tree node ...
- BZOJ 3639: Query on a tree VII
Description 一棵树,支持三种操作,修改点权,修改颜色,问所有与他路径上颜色相同的点的最大权,包含这两个点. Sol LCT. 用LCT来维护重边,对于每个节点在建一个set用来维护轻边,这 ...
- 2019.02.17 spoj Query on a tree VII(链分治)
传送门 跟QTREE6QTREE6QTREE6神似,改成了求连通块里的最大值. 于是我们对每条链开一个heapheapheap维护一下即可. MDMDMD终于1A1A1A链分治了. 代码: #incl ...
- BZOJ 3639: Query on a tree VII LCT_set维护子树信息
用 set 维护子树信息,细节较多. Code: #include <cstring> #include <cstdio> #include <algorithm> ...
- [spojQTREE7]Query on a tree VII
即QTREE5和QTREE6组合,即将原本维护子树范围内点数改为维护子树范围内最小值即可,由于最小值没有可减性,因此需要使用set (虽然形式上与QTREE5类似,但QTREE5维护的信息更巧妙一些, ...
- HDU 6191 Query on A Tree(字典树+离线)
Query on A Tree Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Othe ...
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
随机推荐
- 在JS中,将text框中数据格式化,根据不同的小数位数,格式化成对应的XXX,XXX,XXX.XX(2位小数) 或者XXX,XXX,XXX(0位小数)
//在JS中,将text框中数据格式化,根据不同的小数位数,格式化成对应的XXX,XXX,XXX.XX(2位小数) 或者XXX,XXX,XXX(0位小数) function formatNum(num ...
- linux命令之网络管理命令(上)
1.ifconfig:配置或显示网络接口信息 该命令用于配置网卡IP地址等网络参数或显示当前网络的接口状态,该命令配置网卡信息时必须要以root用户的身份来执行. 参数选项 说明 up 激活指定的网络 ...
- python index()函数
python内置index()函数 index() 方法检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,该方法与 python ...
- [51nod] 1090 3个数和为0 暴力+二分
给出一个长度为N的无序数组,数组中的元素为整数,有正有负包括0,并互不相等.从中找出所有和 = 0的3个数的组合.如果没有这样的组合,输出No Solution.如果有多个,按照3个数中最小的数从小到 ...
- “全栈2019”Java第四十九章:重载与重写对比详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- STR[#6]
photo 小明在旅游的路上看到了一条美丽的河,河上有许多船只,有的船只向左航行,有的船只向右航行.小明希望拍下这一美丽的风景,并且把尽可能多的船只都完整地拍到一张照片中. 小明位于河的边上,并且可以 ...
- 面向对象中的__slots__
类中的__slots__ 正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性. 而要限制class的属性就需要用到__sl ...
- 关于前后台DOM树应用
Dom对象是在程序开发中很实用而且经常会应用到的技术,通过Dom对象可以传递具有树结构的对象,有利用前台页面的诸如树的显示和相应值的处理,本文从两个方面全面解析Dom对象的应用,一是从后台得到完整的D ...
- UITextInputMode
An instance of the UITextInputMode class represents the current text-input mode. You can use this ob ...
- python 常用模块大全
1.getpass 模块 一般用于获取用户输入的密码 import getpass pwd = getpass.getpass('input your pass') print(pwd) print ...