Description:

给你一棵n个点的树,编号1~n。每个点可以是黑色,可以是白色。初始时所有点都是黑色。下面有两种操作请你操作给我们看:

0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥有相同的颜色

1 u:翻转u的颜色

Hint:

\(n\le 10^5\)

Solution:

这题我一开始用树剖写,然后随机数据跑得飞快,交上去被菊花图卡飞23333333

树剖正解,详见https://www.cnblogs.com/ivorysi/p/10103010.html

但是.......树剖写法太毒瘤了!!!

所以这里介绍的是LCT做法

不得不说比较巧妙

考虑用2颗LCT维护两种颜色的联通块

并且把点的颜色存到边上

每次修改就在一颗LCT上断边,另一颗LCT上连这条边

同时LCT维护子树信息,询问直接搞就行了

我的LCT还是太菜了,看了好久才看懂

#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=1e6+5;
int n,m,cnt=1;
int f[mxn],hd[mxn],col[mxn]; inline int read() {
char c=getchar(); int x=0,f=1;
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
return x*f;
}
inline void chkmax(int &x,int y) {if(x<y) x=y;}
inline void chkmin(int &x,int y) {if(x>y) x=y;} struct ed {
int to,nxt;
}t[mxn<<1]; inline void add(int u,int v) {
t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
} struct LCT {
int fa[mxn],s[mxn],sz[mxn],ch[mxn][2];
void push_up(int x) {
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+s[x]+1;
}
int isnotrt(int x) {
return ch[fa[x]][0]==x||ch[fa[x]][1]==x;
}
void rotate(int x) {
int y=fa[x],z=fa[y],tp=ch[y][1]==x;
if(isnotrt(y)) ch[z][ch[z][1]==y]=x; fa[x]=z;
ch[y][tp]=ch[x][tp^1]; fa[ch[x][tp^1]]=y;
ch[x][tp^1]=y; fa[y]=x;
push_up(y),push_up(x);
}
void splay(int x) {
while(isnotrt(x)) {
int y=fa[x],z=fa[y];
if(isnotrt(y))
(ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);
rotate(x);
}
}
void access(int x) {
for(int y=0;x;x=fa[y=x]) {
splay(x);
s[x]+=sz[ch[x][1]];
ch[x][1]=y;
s[x]-=sz[ch[x][1]];
}
}
int findrt(int x) {
access(x); splay(x);
while(ch[x][0]) x=ch[x][0];
splay(x); return x;
}
void link(int x) {
splay(x); fa[x]=f[x];
int y=f[x]; access(y); splay(y);
s[y]+=sz[x]; sz[y]+=sz[x];
}
void cut(int x) {
access(x); splay(x);
ch[x][0]=fa[ch[x][0]]=0;
push_up(x);
}
}lct[2]; void dfs(int u,int fa) {
for(int i=hd[u];i;i=t[i].nxt) {
int v=t[i].to;
if(v==fa) continue ;
dfs(v,u); f[v]=u; lct[0].link(v);
}
} int main()
{
n=read(); int u,v;
for(int i=1;i<=n+1;++i) lct[0].sz[i]=lct[1].sz[i]=1; //千万不要忘记赋初值
for(int i=1;i<n;++i) {
u=read(); v=read();
add(u,v); add(v,u);
}
dfs(1,0); f[1]=n+1; //1节点也必须有父亲
lct[0].link(1); m=read();
for(int i=1;i<=m;++i) {
u=read(); v=read();
if(u==1) lct[col[v]].cut(v),lct[col[v]^=1].link(v);
else {
int tp=lct[col[v]].findrt(v);
printf("%d\n",lct[col[v]].sz[lct[col[v]].ch[tp][1]]);
}
}
return 0;
}

[QTree6]Query on a tree VI的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. QTREE6&&7 - Query on a tree VI &&VII

    树上连通块 不用具体距离,只询问连通块大小或者最大权值 可以类比Qtree5的方法,但是记录东西很多,例如子树有无0/1颜色等 一个trick,两个LCT分离颜色 每个颜色在边上. 仅保留连通块顶部不 ...

随机推荐

  1. C++ Primer 笔记——标准库类型string

    1.如果使用等号初始化一个变量,实际上执行的是拷贝初始化,编译器吧等号右侧的初始值拷贝到新创建的对象中去:如果不使用等号则执行的是直接初始化. std::string str = "Test ...

  2. 小米8如何root

    现身说法,实测有效,也踩坑很多. 0. 准备手机.数据线.windows系统的电脑.小米帐号,各一个. 手机需要装上sim卡:电脑需要能上网.最好是有wifi的环境,用来下载安装包. 注意提前备份数据 ...

  3. IDEA 小白采坑

    IDEA Debug状态下,断点第一次可以进去,之后都不能进去 调试时候不要用Ctrl+F9,如果是点击Tool Windows 上的图标的话,也要注意改图标的快捷键是不是Ctrl+F9 Ctrl+F ...

  4. 【bzoj1264】[AHOI2006]基因匹配Match 树状数组

    题解: 一道比较简单的题目 容易发现状态数只有5*n个 而转移需要满足i1<i2;j1<j2 那么很明显是二维平面数点 暴力一点就是二维树状数组+map 5nlog^3 比较卡常 但是注意 ...

  5. 基于nopcommerce b2c开源项目的精简版开发框架Nop.Framework

    http://www.17ky.net/soft/70612.html?v=1#0-sqq-1-39009-9737f6f9e09dfaf5d3fd14d775bfee85 项目详细介绍 该开源项目是 ...

  6. Codeforces 311D Interval Cubing 数学 + 线段树 (看题解)

    Interval Cubing 这种数学题谁顶得住啊. 因为 (3 ^ 48) % (mod - 1)为 1 , 所以48个一个循环节, 用线段树直接维护. #include<bits/stdc ...

  7. mySql版本的相关问题:com.mysql.cj.jdbc.Driver和com.mysql.jdbc.Driver

    Mysql版本的相关问题:com.mysql.cj.jdbc.Driver和com.mysql.jdbc.Driver 1. 在使用mysql时,控制台日志报错如下: Loading class `c ...

  8. springboot拦截器中获取配置文件值

    package com.zhx.web.interceptor; import com.zhx.util.other.IpUtil; import org.slf4j.Logger; import o ...

  9. springmvc controller动态设置content-type

    springmvc  RequestMappingHandlerAdapter#invokeHandlerMethod 通过ServletInvocableHandlerMethod#invokeAn ...

  10. 每月学习数理统计--《统计学习方法—李航》(3): SVM

    1. SVM的最优化问题 2.拉格朗日乘数法,对偶条件KKT条件 3.软件隔支持向量机 4.非线性支持向量机,核函数 5.SMO算法 1. SVM的最优化问题 支持向量机(Support Vector ...