CodeForces 343D 线段树维护dfs序
给定一棵树,初始时树为空
操作1,往某个结点注水,那么该结点的子树都注满了水
操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了
操作3,询问某个点是否有水
我们将树进行dfs, 生成in[u], 访问结点u的时间戳,out[u],离开结点u的时间戳
每个结点的in值对应在线段树中的区间的一点
那么对于操作1, 只要将区间[in[u],out[u]] 的值都改为1, 但是如果区间[in[u],out[u]] 原先存在为0的点,那么父区间肯定是空的,这个操作不能
改变父区间的状态,所以需要将in[fa[u]]置为0,
对于操作2,只要将in[u] 置为0就行了
对于操作3,只要区间[in[u],out[u]]内不存在为0的点,那么点u就是有水的
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
const int INF = <<;
/*
我们对树进行dfs,求出dfs序列 in[] 和out[] 用线段树维护这个序列
操作1就是将[in[b],out[b]]区间内的点都变为1 , 如果区间内存在0,那么要将b的父结点更新为0,因为虽然更新了[in[b],out[b]],但是祖先不会变
操作2就是将点in[b]置为0
操作3就是看区间[in[b],out[b]] 所以不仅可以将树进行树链剖分,然后用线段树维护
还可以用线段树维护树的dfs序列
*/
const int N = + ;
int in[N], out[N], num, fa[N];
int tree[N * ], laze[N * ];
vector<int> g[N];
void dfs(int u)
{
in[u] = ++num;
for (int i = ; i < g[u].size(); ++i)
{
int v = g[u][i];
if (v != fa[u])
{
fa[v] = u;
dfs(v);
}
}
out[u] = num;
}
void pushDown(int rt)
{
if (laze[rt]==)
{
tree[rt << ] = tree[rt << | ] = laze[rt << ] = laze[rt << | ] = ;
laze[rt] = ;
}
}
void pushUp(int rt)
{
if (tree[rt << ] == || tree[rt << | ] == )
tree[rt] = ;
else
tree[rt] = ;
}
bool flag = false;
void update(int l, int r, int rt, int L, int R, int val)
{
pushDown(rt);
if (L<=l && R>=r)
{
if (tree[rt] == )
flag = true;
tree[rt] = val;
laze[rt] = val;
return;
}
int mid = (l + r) >> ;
if (L <= mid)
update(l, mid, rt << , L, R, val);
if (R > mid)
update(mid + , r, rt << | , L, R, val);
pushUp(rt);
} void query(int l, int r, int rt, int L, int R)
{
pushDown(rt);
if (L<=l && R>=r)
{
//区间内有一个是0,那么所访问的点(根)就是0
if (tree[rt] == )
flag = false;
return;
}
int mid = (l + r) >> ;
if (L <= mid)
query(l, mid, rt << , L, R);
if (R > mid)
query(mid + , r, rt << | , L, R);
pushUp(rt);
}
int main()
{
//freopen("d:/in.txt", "r", stdin);
int n, q, a, b,x, y;
scanf("%d", &n);
for (int i = ; i < n; ++i)
{
scanf("%d%d", &a, &b);
g[a].push_back(b);
g[b].push_back(a);
}
fa[] = ;
dfs();
scanf("%d", &q);
while (q--)
{
scanf("%d%d", &a, &b);
if (a == )
{
flag = false;
//将区间内的点都置为1
update(, n, , in[b], out[b],);
//如果区间内存在0的点,那么fa[b]肯定为空,
if (flag&&fa[b]!=)
{
update(, n, , in[fa[b]],in[fa[b]],);
}
}
else if (a == )
{
update(, n, , in[b],in[b],);
}
else
{
flag = true;
query(,n, , in[b], out[b]);
if (flag)
printf("1\n");
else
printf("0\n");
}
}
return ;
}
CodeForces 343D 线段树维护dfs序的更多相关文章
- CF877E Danil and a Part-time Job 线段树维护dfs序
\(\color{#0066ff}{题目描述}\) 有一棵 n 个点的树,根结点为 1 号点,每个点的权值都是 1 或 0 共有 m 次操作,操作分为两种 get 询问一个点 x 的子树里有多少个 1 ...
- P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA
\(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...
- bzoj 3779: 重组病毒【LCT+线段树维护dfs序】
%.8lf会WA!!%.8lf会WA!!%.8lf会WA!!要%.10lf!! 和4817有点像,但是更复杂. 首先对于操作一"在编号为x的计算机中植入病毒的一个新变种,在植入一个新变种时, ...
- BZOJ 4817 [SDOI2017]树点涂色 (LCT+线段树维护dfs序)
题目大意:略 涂色方式明显符合$LCT$里$access$操作的性质,相同颜色的节点在一条深度递增的链上 用$LCT$维护一个树上集合就好 因为它维护了树上集合,所以它别的啥都干不了了 发现树是静态的 ...
- 【HIHOCODER 1576】 子树中的最小权值(线段树维护DFS序)
描述 给定一棵N个节点的树,编号1~N.其中1号节点是根,并且第i个节点的权值是Vi. 针对这棵树,小Hi会询问小Ho一系列问题.每次小Hi会指定一个节点x,询问小Ho以x为根的子树中,最小的权值是多 ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- codeforces 877 E. Danil and a Part-time Job(线段树(dfs序))
题目链接:http://codeforces.com/contest/877/problem/E 题解:显然一看就感觉要么树链剖分要么线段树+dfs序,题目要求的操作显然用线段树+dfs序就可以实现. ...
- 2018.11.01 NOIP训练 图论(线段树+倍增+dfs序)
传送门 一道挺妙的题. 对于询问点(u,v),如右图所示,我们可以发现存在一个点m在u->v的路径中,m子树的点到u是最近的,m子树外到v是最近的.其中dis(u,m)=(dis(u,v)-1) ...
- Codeforces 343D 线段树
题意:给你一颗以点1为根的数,有两种操作,一种是把x及其子树的所有点都灌满水,一种是把x及其所有祖先都放空水,一种是询问,问某个点里有没有水? 思路:看网上大多数是树剖,但实际上5e5的数据树剖还是有 ...
随机推荐
- [Android学习笔记]Android向下兼
Android向下兼容的思路:使用高版本的API,在运行时判断真实运行平台的API版本,根据不同版本做不同的处理 关键类:Build.class里面定义了API版本相关信息 内部类:VERSION定义 ...
- 精讚部落::MySQL 的MEMORY engine
精讚部落::MySQL 的MEMORY engine MySQL 的MEMORY engine 無次要群組
- jqueryUI中datepicker的使用,解决与asp.net中的UpdatePanel联合使用时的失效问题
1.jqueryUI的datepicker的使用 -->首先在jqueryUI官网上根据你的需要下载适合你系统主题的样式,jqueryUI主题下载地址: -->下载后的文件 jquery- ...
- Nubia Z5S 基于官方H207/4.4内核的Mokee4.4.4 RC3.2 (2014.7.31修复呼吸灯(能亮依旧不能呼吸))
特别感谢 yun3195 和 轻描淡写Yhw 帮忙測试 转帖请务必注明本链接地址: http://blog.csdn.net/syhost/article/details/36444259 此ROM ...
- 14.5.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量
14.5.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量 改变InnoDB redo ...
- poj 1743 男人八题之后缀数组求最长不可重叠最长重复子串
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 14874 Accepted: 5118 De ...
- 30分钟快速掌握AngularJs
[后端人员耍前端系列]AngularJs篇:30分钟快速掌握AngularJs 一.前言 对于前端系列,自然少不了AngularJs的介绍了.在前面文章中,我们介绍了如何使用KnockoutJs来 ...
- CountDownLatch和CyclicBarrier的区别(转)
在网上看到很多人对于CountDownLatch和CyclicBarrier的区别简单理解为CountDownLatch是一次性的,而CyclicBarrier在调用reset之后还可以继续使用.那如 ...
- oracle数据库单个数据文件的大小限制
之前没有仔细想过这个问题,因为总是不会用到,也没有犯过类似错误. 顺便提一下学习方法吧. 卤肉的学习方法是:常用知识点,熟悉理论并反复做实验,深入理解:不常用的知识点,相关内容都了解大概,遇到问题时想 ...
- Java 建立mysql数据库连接的语句
每次在面试时被问到jdbc的数据路链接过程都卡着,这次不怕了,背会了... 第一个,比较粗糙的 try{ Class.forName("com.mysql.jdbc.Driver&quo ...