BZOJ 3639: Query on a tree VII LCT_set维护子树信息
用 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维护子树信息的更多相关文章
- BZOJ 3637: Query on a tree VI LCT_维护子树信息_点权转边权_好题
非常喜欢这道题. 点权转边权,这样每次在切断一个点的所有儿子的时候只断掉一条边即可. Code: #include <cstring> #include <cstdio> #i ...
- BZOJ 3639: Query on a tree VII
Description 一棵树,支持三种操作,修改点权,修改颜色,问所有与他路径上颜色相同的点的最大权,包含这两个点. Sol LCT. 用LCT来维护重边,对于每个节点在建一个set用来维护轻边,这 ...
- bzoj 3083 遥远的国度——树链剖分+线段树维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 int 的范围是 2^31 - 1 ,所以权值是不是爆 int 了…… O( nlog ...
- BZOJ 3306: 树 LCT + set 维护子树信息
可以作为 LCT 维护子树信息的模板,写的还是比较优美的. 本地可过,bzoj 时限太紧,一直 TLE #include<bits/stdc++.h> #define setIO(s) f ...
- 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 ...
- [spojQTREE7]Query on a tree VII
即QTREE5和QTREE6组合,即将原本维护子树范围内点数改为维护子树范围内最小值即可,由于最小值没有可减性,因此需要使用set (虽然形式上与QTREE5类似,但QTREE5维护的信息更巧妙一些, ...
- SP16549 QTREE6 - Query on a tree VI LCT维护颜色联通块
\(\color{#0066ff}{ 题目描述 }\) 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v ...
- bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 LCT维护子树 siz .设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的si ...
- bzoj 3779 重组病毒——LCT维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3779 调了很久……已经懒得写题解了.https://www.cnblogs.com/Zinn ...
随机推荐
- nyoj--301--递推求值(经典矩阵运算)
递推求值 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给你一个递推公式: f(x)=a*f(x-2)+b*f(x-1)+c 并给你f(1),f(2)的值,请求出f(n ...
- (转载) android快速搭建项目积累
android快速搭建项目积累 2016-04-05 20:07 519人阅读 评论(0) 收藏 举报 分类: android优化(8) Rx技术(5) 版权声明:本文为博主原创文章,未经博主 ...
- HDU 1587 Flowers【贪心】
题意:给出n种花的价钱,和总的金额m,问最多能够买到多少朵花.先排序,然后就是便宜的花在能够买的范围内能够多买就多买 #include<iostream> #include<cstd ...
- lua中调用C++函数
lua中调用C++函数 我们产品中提供了很多lua-C API给用户在lua中调用,之前一直没用深究其实现原理,只是根据已有的代码在编码.显然这不是一个好的习惯,没用达到知其所以然的目的. 一.基本原 ...
- Hdu 2586 树链剖分求LCA
Code: #include<cstdio> #include<cstring> #include<vector> #include<algorithm> ...
- UE4自学随笔(一)
本文及后续均为个人学习记录所用,难免毫无章法零零碎碎,希望看到此文的诸君勿怪. 一.Actor与Pawn Actor类 在UE4中,Actor类是可以放到游戏场景中的游戏对象的基本类型.你如果想放置任 ...
- LightOJ-1259 Goldbach`s Conjecture 数论 素数筛
题目链接:https://cn.vjudge.net/problem/LightOJ-1259 题意 给一个整数n,问有多少对素数a和b,使得a+b=n 思路 素数筛 埃氏筛O(nloglogn),这 ...
- luogu P1365 WJMZBMR打osu! / Easy(期望DP)
题目背景 原 维护队列 参见P1903 题目描述 某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:( 我们来简化一下这个游戏的规则 有nnn次点击要做,成功了就是o,失败了就是 ...
- luogu P1630 求和(枚举暴力)
题意 题解 可以发现当a=10001时, 和1是等价的. 所以这题就水了. #include<iostream> #include<cstring> #include<c ...
- Linux学习之计算机基础理论
一.描述计算机的组成及其功能. 计算机系统是由硬件系统(hardware)和软件系统(software system)两部分组成. 硬件系统: 从硬件基本结构上来讲,计算机是由运算器.控制器.存储器. ...