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的更多相关文章

  1. 洛谷SP16580 QTREE7 - Query on a tree VII(LCT,multiset)

    洛谷题目传送门 思路分析 维护子树最值还是第一次写QwQ 因为子树的最值会变化,所以不能简单地把最值记下来,还要维护一个平衡树,把每个子树的最大值扔进去,来资磁插入.删除和查询最值. 然后我就懒得手写 ...

  2. SP16580 QTREE7 - Query on a tree VII(LCT)

    题意翻译 一棵树,每个点初始有个点权和颜色(输入会给你) 0 u:询问所有u,v路径上的最大点权,要满足u,v路径上所有点颜色相同 1 u:反转u的颜色 2 u w:把u的点权改成w 题解 Qtree ...

  3. bzoj3639: Query on a tree VII

    Description You are given a tree (an acyclic undirected connected graph) with n nodes. The tree node ...

  4. BZOJ 3639: Query on a tree VII

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

  5. 2019.02.17 spoj Query on a tree VII(链分治)

    传送门 跟QTREE6QTREE6QTREE6神似,改成了求连通块里的最大值. 于是我们对每条链开一个heapheapheap维护一下即可. MDMDMD终于1A1A1A链分治了. 代码: #incl ...

  6. BZOJ 3639: Query on a tree VII LCT_set维护子树信息

    用 set 维护子树信息,细节较多. Code: #include <cstring> #include <cstdio> #include <algorithm> ...

  7. [spojQTREE7]Query on a tree VII

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

  8. HDU 6191 Query on A Tree(字典树+离线)

    Query on A Tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Othe ...

  9. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

随机推荐

  1. SOLR企业搜索平台 二 (分词安装)

    标签:linux lucene 分词 solr 全文检索 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://3961409.blog ...

  2. Java之static静态代码块

    Java之static静态代码块 构造代码块 使用{}包裹的代码区域,这里的代码区域特指位于class{}下面的而不是存在于其他type method(){}这类函数下面的代码区域 public cl ...

  3. gulp 图片、样式、js、实时刷新等压缩gulpfile.js文件各个模块

    1.压缩tinypng图片   gulp-tinypng-nokey,但不压缩gif格式(另外一个gulp-imagemin压缩率不高,可以压缩gif格式) // 获取 gulp var gulp = ...

  4. maven(私库)上传jar包

    在实际开发过程中,我们经常会遇到需要引用的jar依赖,在我们公司的maven仓库不存在,这个时候我们就需要把jar上传上去,在项目中添加对应依赖就OK了. 步骤1:下载jar 在http://mvnr ...

  5. 【loj#6503.】「雅礼集训 2018 Day4」Magic(生成函数+容斥)

    题面 传送门 题解 复杂度比较迷啊-- 以下以\(n\)表示颜色总数,\(m\)表示总的卡牌数 严格\(k\)对比较难算,我们考虑容斥 首先有\(i\)对就代表整个序列被分成了\(m-i\)块互不相同 ...

  6. str中的join方法; set集合;深浅拷贝

    一.str中的join方法 1,用join可以吧列表转换为字符串 将列表转换成字符串. 每个元素之间用_拼接 s = "_". join(['德玛', ''赵信'', '易']) ...

  7. SSO单点登录入门

    1,SSO简介 SSO(Single Sign-On,单点登录)是身份管理中的一部分.SSO 的一种较为通俗的定义是:SSO 是指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过 ...

  8. django中多个app放入同一文件apps

    新建一个apps文件夹 需要整理的app文件夹拖到同一个文件夹中,即apps.(弹出对话框,取消勾选Search for references) 在pycharm中,右键apps文件夹--选择mark ...

  9. yolov3源码分析keras(二)损失函数计算

    一.前言 损失函数计算主要分析两部分一部分是yolo_head函数的分析另一部分为ignore_mask的生成的分析. 二.重要细节分析 2.1损失函数计算具体代码及部分分析 def yolo_los ...

  10. python update()

    Python 字典 update() 函数把字典参数 dict2 的 key/value(键/值) 对更新到字典 dict 里. dict.update(dict2) 如果dict2里的键和dict1 ...