用 set 维护子树信息,细节较多。

Code:

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#define setIO(s) freopen(s".in","r",stdin), freopen(s".out","w",stdout)
#define maxn 100009
#define inf -2147483647
using namespace std;
int fat[maxn];
int n,m;
struct Graph{
int head[maxn],to[maxn<<1],nex[maxn<<1],cnt;
void addedge(int u,int v){ nex[++cnt]=head[u],head[u]=cnt,to[cnt]=v; }
void dfs(int u,int father){
fat[u]=father;
for(int v=head[u];v;v=nex[v]) if(to[v]!=father) dfs(to[v],u);
}
void Build(){
for(int i=1;i<n;++i){
int a,b;
scanf("%d%d",&a,&b), addedge(a,b),addedge(b,a);
}
dfs(1,0);
}
}G;
int col[maxn],v[maxn];
struct LCT{
multiset<int>s[maxn];
multiset<int>::reverse_iterator rit;
int ch[maxn][2],f[maxn];
int siz[maxn],mx[maxn];
void init(){ mx[0]=-2147483647; }
int value(int x) { rit=s[x].rbegin(); return (*rit); }
int get(int x){ return ch[f[x]][1]==x; }
int lson(int x){ return ch[x][0];}
int rson(int x){ return ch[x][1];}
int isRoot(int x){ return !(ch[f[x]][0]==x||ch[f[x]][1]==x); }
void pushup(int x){
if(!x) return;
mx[x]=max(v[x],max(mx[lson(x)],mx[rson(x)]));
if(!s[x].empty()) mx[x]=max(mx[x],value(x));
}
void rotate(int x)
{
int old=f[x],oldf=f[old],which=get(x);
if(!isRoot(old)) ch[oldf][ch[oldf][1]==old]=x;
ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
ch[x][which^1]=old,f[old]=x,f[x]=oldf;
pushup(old),pushup(x);
}
void splay(int x)
{
int u=x;
while(!isRoot(u)) u=f[u];
u=f[u];
for(int fa;(fa=f[x])!=u;rotate(x))
if(f[fa]!=u) rotate(get(fa)==get(x)?fa:x);
}
void Access(int x){
for(int y=0;x;y=x,x=f[x]){
splay(x);
if(rson(x)) s[x].insert(mx[rson(x)]);
if(ch[x][1]=y) s[x].erase(s[x].find(mx[y])) ;
pushup(x);
}
}
void cut(int a,int b){
if(!a) return;
Access(b),splay(b),ch[b][0]=f[ch[b][0]]=0,pushup(b);
}
void link(int a,int b)
{
if(!a) return;
Access(a),splay(a),Access(b),splay(b);
f[b]=a,ch[a][1]=b,pushup(a);
}
int findRoot(int a){
Access(a),splay(a);
while(ch[a][0]) a=ch[a][0];
return a;
}
}tree[2];
int main(){
//setIO("debug");
scanf("%d",&n),G.Build(),tree[0].init(),tree[1].init();
for(int i=1;i<=n;++i) scanf("%d",&col[i]);
for(int i=1;i<=n;++i) scanf("%d",&v[i]);
fat[1]=n+1,v[n+1]=tree[1].mx[n+1]=tree[0].mx[n+1]=inf;
for(int i=1;i<=n;++i) tree[col[i]].link(fat[i],i);
int opt,a;
scanf("%d",&m);
for(int i=1;i<=m;++i){
scanf("%d%d",&opt,&a);
if(opt==0) {
int x=tree[col[a]].findRoot(a);
tree[col[a]].splay(x);
if(col[x]==col[a]) printf("%d\n",tree[col[a]].mx[x]);
else printf("%d\n",tree[col[a]].mx[tree[col[a]].ch[x][1]]);
}
if(opt==1) {
tree[col[a]].cut(fat[a],a),col[a]^=1,tree[col[a]].link(fat[a],a);
}
if(opt==2)
{
tree[col[a]].Access(a),tree[col[a]].splay(a);
scanf("%d",&v[a]);
tree[col[a]].pushup(a);
}
}
return 0;
}

  

BZOJ 3639: Query on a tree VII LCT_set维护子树信息的更多相关文章

  1. BZOJ 3637: Query on a tree VI LCT_维护子树信息_点权转边权_好题

    非常喜欢这道题. 点权转边权,这样每次在切断一个点的所有儿子的时候只断掉一条边即可. Code: #include <cstring> #include <cstdio> #i ...

  2. BZOJ 3639: Query on a tree VII

    Description 一棵树,支持三种操作,修改点权,修改颜色,问所有与他路径上颜色相同的点的最大权,包含这两个点. Sol LCT. 用LCT来维护重边,对于每个节点在建一个set用来维护轻边,这 ...

  3. bzoj 3083 遥远的国度——树链剖分+线段树维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 int 的范围是 2^31 - 1 ,所以权值是不是爆 int 了…… O( nlog ...

  4. BZOJ 3306: 树 LCT + set 维护子树信息

    可以作为 LCT 维护子树信息的模板,写的还是比较优美的. 本地可过,bzoj 时限太紧,一直 TLE #include<bits/stdc++.h> #define setIO(s) f ...

  5. bzoj 3637: Query on a tree VI 树链剖分 && AC600

    3637: Query on a tree VI Time Limit: 8 Sec  Memory Limit: 1024 MBSubmit: 206  Solved: 38[Submit][Sta ...

  6. [spojQTREE7]Query on a tree VII

    即QTREE5和QTREE6组合,即将原本维护子树范围内点数改为维护子树范围内最小值即可,由于最小值没有可减性,因此需要使用set (虽然形式上与QTREE5类似,但QTREE5维护的信息更巧妙一些, ...

  7. SP16549 QTREE6 - Query on a tree VI LCT维护颜色联通块

    \(\color{#0066ff}{ 题目描述 }\) 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v ...

  8. bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 LCT维护子树 siz .设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的si ...

  9. bzoj 3779 重组病毒——LCT维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3779 调了很久……已经懒得写题解了.https://www.cnblogs.com/Zinn ...

随机推荐

  1. codeblocks开源的c、c++编译器,小巧方便

    1.下载带gun的版本 2.设置编译的位置 3.创建项目 4.执行项目 有意思的开源的c编译器 ~~~

  2. xBIM 基础07 创建WebBIM文件

    系列目录    [已更新最新开发文章,点击查看详细]  xBIM项目提供了一个IFC文件的Web查看器.当你想把IFC转换成紧凑的WexBIM时,需要 xBIM Essentials 和 xBIM G ...

  3. sql server Delete误操作后如何恢复数据

    声明:本文是根据别人的经验https://blog.csdn.net/dba_huangzj/article/details/8491327写的总结 说明:update和delete时没有加where ...

  4. wordpress 后台登录增加访问效验

    目前已知的增加 wordpress 后台登录安全的方案有三种: 安全插件:如Limit Login Attempts Reloaded.WPS Hide Login 等等: 登录 URL 增加自定义k ...

  5. 计算机组成原理--64位CPU装载32位操作系统,它的寻址能力还是4GB吗?

    借由这个问题,今天我们就把 32 位 CPU.64 位 CPU.32 位操作系统.64 位操作系统之间的区别与联系彻底搞清楚.对于这个问题,博主也是一知半解了好长时间啊~ 基本概念 32位的CPU与6 ...

  6. 字符串的格式化(转自武sir)

    百分号s方式: (name)      可选,用于选择指定的key flags          可选,可供选择的值有: +       右对齐:正数前加正好,负数前加负号: -        左对齐 ...

  7. 小程序QQ版表情解析组件

    代码片段: [https://developers.weixin.qq.com/s/KLaD5MmD7V45) GitHub: https://github.com/WozHuang/Miniprog ...

  8. UE4.18.3 C++项目无法打开C++类问题(VS2017)

    升级VS2017后,突然出现UE4创建C++项目无法打开VS问题.经过测试为VS2017升级后C++的桌面开发工具集采用了VC++2017 v141工具集,而UE4对该工具集尚未兼容,故找不到vs打开 ...

  9. [codevs3955]最长严格上升子序列(加强版)

    题目大意:给你一个序列,要你求该序列中最长严格上升子序列的长度. 解题思路:此题算是一道LIS模板题.普通的$O(n^2)$的LIS是会TLE的,因为$n\le 1000000$,所以此题要用单调队列 ...

  10. 微信小程序 上传图片

    效果图  如上,js  如下,在页面循环图片就可以 /** * 选择图片 */ uploadImgAdd: function(e) { var imgs = this.data.imgs; wx.ch ...