树上连通块

不用具体距离,只询问连通块大小或者最大权值

可以类比Qtree5的方法,但是记录东西很多,例如子树有无0/1颜色等

一个trick,两个LCT分离颜色

每个颜色在边上。

仅保留连通块顶部不是相同颜色,使得断边不会被菊花图卡掉

所以内部颜色不用考虑了,专心维护子树值。

查询时候findrt,splay,右儿子即可。

Qtree6

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');} namespace Miracle{
const int N=+;
int n,m;
int f[N];
int co[N];
struct LCT{
#define ls ch[x][0]
#define rs ch[x][1]
int fa[N],ch[N][];
int sz[N],si[N];
bool nrt(int x){
return ch[fa[x]][]==x||ch[fa[x]][]==x;
}
void pushup(int x){
if(x)
sz[x]=si[x]+sz[ls]+sz[rs]+;
}
void rotate(int x){
int y=fa[x],d=ch[y][]==x;
fa[ch[y][d]=ch[x][!d]]=y;
if(nrt(y)) ch[fa[x]=fa[y]][ch[fa[y]][]==y]=x;
else fa[x]=fa[y];
fa[ch[x][!d]=y]=x;
pushup(y);
}
void splay(int x){
while(nrt(x)){
int y=fa[x],z=fa[y];
if(nrt(y)){
rotate((ch[y][]==x)==(ch[z][]==y)?y:x);
}
rotate(x);
}
pushup(x);
}
void access(int x){
for(reg y=;x;y=x,x=fa[x]){
//cout<<" xx "<<x<<endl;
splay(x);si[x]-=sz[y];si[x]+=sz[ch[x][]];
ch[x][]=y;
pushup(x);
}
}
int findrt(int x){
access(x);splay(x);
while(ch[x][]) x=ch[x][];
splay(x);
return x;
}
void link(int x){
//cout<<" link "<<x<<endl;
splay(x);
int y=fa[x]=f[x];
access(y);splay(y);
si[y]+=sz[x];
pushup(y);
}
void cut(int x){
// cout<<" cut "<<x<<endl;
access(x);splay(x);
// cout<<ls<<" "<<ch[x][0]<<endl;
ls=fa[ls]=;
pushup(x);
}
int query(int x){
int lp=findrt(x);
// cout<<" lp "<<lp<<" "<<sz[lp]<<" "<<si[lp]<<endl;
return sz[lp]-si[lp]-;
}
}lct[];
vector<int>to[N];
void dfs(int x){
for(reg i=;i<(int)to[x].size();++i){
if(to[x][i]!=f[x]){
f[to[x][i]]=x;dfs(to[x][i]);
lct[].link(to[x][i]);
}
}
}
int main(){
rd(n);
int x,y;
for(reg i=;i<n;++i)rd(x),rd(y),to[x].push_back(y),to[y].push_back(x);
for(reg i=;i<=n+;++i) lct[].sz[i]=,lct[].sz[i]=,co[i]=;
to[n+].push_back();
dfs(n+);
int op;
rd(m);
while(m--){
rd(op);rd(x);
if(!op){
printf("%d\n",lct[co[x]].query(x));
}else{
lct[co[x]].cut(x);
// cout<<" after co[x] cut "<<endl;
lct[co[x]^].link(x);
co[x]^=;
}
}
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/3/15 10:57:40
*/

Qtree7

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');} namespace Miracle{
const int N=1e5+;
const int inf=0x3f3f3f3f;
int n,m;
int fa[N];
struct LCT{
struct node{
int ch[],fa;
int val;
int ans;
priority_queue<int>q,d;
void dele(int c){
d.push(c);
}
void ins(int c){
q.push(c);
}
int top(){
while(!q.empty()&&!d.empty()&&q.top()==d.top()) q.pop(),d.pop();
if(!q.empty()) return q.top();
return -inf;
}
}t[N];
bool nrt(int x){
return t[t[x].fa].ch[]==x||t[t[x].fa].ch[]==x;
}
void pushup(int x){
t[x].ans=max(t[x].val,max(t[x].top(),max(t[t[x].ch[]].ans,t[t[x].ch[]].ans)));
}
void rotate(int x){
int y=t[x].fa,d=t[y].ch[]==x;
t[t[y].ch[d]=t[x].ch[!d]].fa=y;
if(nrt(y)) t[t[x].fa=t[y].fa].ch[t[t[y].fa].ch[]==y]=x;
else t[x].fa=t[y].fa;
t[t[x].ch[!d]=y].fa=x;
pushup(y);
}
void splay(int x){
while(nrt(x)){
int y=t[x].fa,z=t[y].fa;
if(nrt(y)){
rotate((t[y].ch[]==x)==(t[z].ch[]==y)?y:x);
}rotate(x);
}
pushup(x);
}
void access(int x){
for(reg y=;x;y=x,x=t[x].fa){
splay(x);t[x].dele(t[y].ans);
t[x].ins(t[t[x].ch[]].ans);
t[x].ch[]=y;
pushup(x);
}
}
int findrt(int x){
access(x);splay(x);
while(t[x].ch[]) x=t[x].ch[];
splay(x);
return x;
}
void link(int x){
// cout<<" link "<<x<<" t.fa "<<t[x].fa<<" fa "<<fa[x]<<" ans "<<t[x].ans<<" val "<<t[x].val<<endl;
splay(x);
int y=t[x].fa=fa[x];
access(y);splay(y);
t[y].ins(t[x].ans);
pushup(y);
}
void cut(int x){
access(x);splay(x);
t[x].ch[]=t[t[x].ch[]].fa=;
pushup(x);
}
void chan(int x,int c){//chan val
access(x);splay(x);
t[x].val=c;
pushup(x);
}
int query(int x){
int lp=findrt(x);
return t[t[lp].ch[]].ans;
}
}lct[];
vector<int>to[N];
int co[N],wei[N];
void dfs(int x){
//cout<<x<<endl;
for(reg i=;i<(int)to[x].size();++i){
int y=to[x][i];
if(y==fa[x]) continue;
fa[y]=x;
dfs(y);
lct[co[y]].link(y);
}
}
int main(){ rd(n);
lct[].t[].ans=lct[].t[].val=-inf;
lct[].t[].ans=lct[].t[].val=-inf;
lct[].t[n+].ans=lct[].t[n+].val=-inf;
lct[].t[n+].ans=lct[].t[n+].val=-inf;
int x,y;
for(reg i=;i<n;++i){
rd(x);rd(y);
to[x].push_back(y);to[y].push_back(x);
}
to[n+].push_back();
for(reg i=;i<=n;++i){
rd(co[i]);
}
for(reg i=;i<=n;++i){
rd(wei[i]);
// cout<<" i "<<i<<" "<<wei[i]<<endl;
lct[].t[i].val=lct[].t[i].ans=wei[i];
lct[].t[i].val=lct[].t[i].ans=wei[i];
}
wei[n+]=-inf;
dfs(n+); rd(m);int op;
while(m--){
rd(op);rd(x);
if(op==){
printf("%d\n",lct[co[x]].query(x));
}else if(op==){
lct[co[x]].cut(x);lct[co[x]^].link(x);
co[x]^=;
}else{
rd(y);
lct[].chan(x,y);
lct[].chan(x,y);
}
}
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/3/15 14:12:29
*/

QTREE6&&7 - Query on a tree VI &&VII的更多相关文章

  1. QTREE6 - Query on a tree VI 解题报告

    QTREE6 - Query on a tree VI 题目描述 给你一棵\(n\)个点的树,编号\(1\)~\(n\).每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我 ...

  2. 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 ...

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

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

  4. [QTree6]Query on a tree VI

    Description: 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括 ...

  5. 洛谷SP16549 QTREE6 - Query on a tree VI(LCT)

    洛谷题目传送门 思路分析 题意就是要维护同色连通块大小.要用LCT维护子树大小就不说了,可以看看蒟蒻的LCT总结. 至于连通块如何维护,首先肯定可以想到一个很naive的做法:直接维护同色连通块,每次 ...

  6. SPOJ 16549 - QTREE6 - Query on a tree VI 「一种维护树上颜色连通块的操作」

    题意 有操作 $0$ $u$:询问有多少个节点 $v$ 满足路径 $u$ 到 $v$ 上所有节点(包括)都拥有相同的颜色$1$ $u$:翻转 $u$ 的颜色 题解 直接用一个 $LCT$ 去暴力删边连 ...

  7. SP16549 QTREE6 - Query on a tree VI(LCT)

    题意翻译 题目描述 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥 ...

  8. SPOJ QTREE6 Query on a tree VI 树链剖分

    题意: 给出一棵含有\(n(1 \leq n \leq 10^5)\)个节点的树,每个顶点只有两种颜色:黑色和白色. 一开始所有的点都是黑色,下面有两种共\(m(1 \leq n \leq 10^5) ...

  9. bzoj3637 CodeChef SPOJ - QTREE6 Query on a tree VI 题解

    题意: 一棵n个节点的树,节点有黑白两种颜色,初始均为白色.两种操作:1.更改一个节点的颜色;2.询问一个节点所处的颜色相同的联通块的大小. 思路: 1.每个节点记录仅考虑其子树时,假设其为黑色时所处 ...

随机推荐

  1. JavaList addAll removeAll

    List<String>list1=new ArrayList<>(); list1.add("a"); list1.add("b"); ...

  2. python学习笔记(4)-基本数据类型-数字类型及操作

    大学mooc 北京理工大学 python语言程序设计课程学习笔记 一.整数类型 可正可负,没有取值范围的限制(这个与c不同,c要考虑数据类型的存储空间).如pow(x,y),计算x的y次方,pow(2 ...

  3. LODOP设置判断后执行哪个

    LODOP的语句是普通的语句,可以通过JS判断确定要执行哪个,或通过循环循环执行一些语句.如果需要执行某些打印项在哪些条件下不打印,不需要通过代码删除打印项,类似LODOP.SET_PRINT_STY ...

  4. vhdl——type

    TYPE 数据类型名 IS 数据类型定义 OF 基本数据类型 TYPE 数据类型名 IS 数据类型定义 常用的用户自定义的数据类型有枚举型,数组型,记录型.其中枚举型的在状态机的描述中经常使用到 ,数 ...

  5. git bash 下操作文件及文件夹命令

    1, cd : change directory的简写,改变目录的意思,就是切换到哪个目录下, 如 cd e:\fff  切换 E 盘下面的fff 目录. 当我们用cd 进入文件夹时,我们可以使用 通 ...

  6. codeforces401C

    Team CodeForces - 401C Now it's time of Olympiads. Vanya and Egor decided to make his own team to ta ...

  7. 【数学建模】day08-数理统计III

    2. 回归分析 回归分析与曲线拟合区分. 曲线拟合是,根据得到的若干有关变量的一组数据,寻找因变量与(一个或几个)自变量之间的一个函数,使这个函数对那组数据拟合得好.通常,函数的形式可以由经验.先验知 ...

  8. ZIP压缩包加密破解

    python多线程破解zip文件,废话不多说直接上代码 # -*- coding: UTF-8 -*- #使用多线程和接受参数的形式去破解指定的zip文件 #python3 zip_file_cack ...

  9. AIM Tech Round 4 Div. 1

    A:显然最优方案是对所形成的置换的每个循环排个序. #include<iostream> #include<cstdio> #include<cmath> #inc ...

  10. 学习Android过程中遇到的问题及解决方法——AS为xutils添加依赖

    在使用xutils时遇到不能添加以来的问题,花了很长时间终于解决,网上添加依赖的方法很多,在此针对个人出现的问题作下笔记. 我本想使用jar包,因为在使用smartImageView时是用的jar包来 ...