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:自定义滚动边缘(EdgeEffect)效果
Android可滚动控件(GridView.ListView.ScrollView等)当用户滚动到头的时候会有个边缘反馈效果,在4.0上默认为Holo蓝色效果. 如果您的App自定义了主题颜色,比如 ...
- 爱在watir(1)----一切从搭讪开始
Tom和Coco是有名的加班狂人.Tom加班改bug,Coco加班回归bug. 两人经常加班到很晚,Tom是男孩子,很自然的担负起护送Coco的任务.他打车先送Coco回去,然后自己回家.不过Tom和 ...
- SPOJ375(树链剖分)
题目:Query on a tree 题意:给定一棵树,告诉了每条边的权值,然后给出两种操作: (1)把第i条边的权值改为val (2)询问a,b路径上权值最大的边 分析:本题与HDU3966差不多, ...
- XPSP2 PSDK(还有lostspeed)
XPSP2 PSDK Full Download with Local Install Use the full download to copy the entire Windows XP SP2 ...
- 理解并解决GBK转UTF-8奇数中文乱码(转)
最近在做一个反馈功能,把数据反馈到对方公司网站,我公司是GBK编码,对方公司是UTF-8编码.因此,我需要将GBK编码数据转换成UTF-8编码数据,这样对方网站才不会乱码.最简单的方法是将HttpCl ...
- 基于Chrome开源提取的界面开发框架开篇--转
初衷 一直希望VC开发者能够方便的开发出细腻高品质的用户界面.我喜欢C++,选择的平台是Windows,所以大部分时间用VC.我自身不排斥其他技术或者开发语言或者开发工具,都去了解,了解的目的是想吸取 ...
- 旧发票要保留SIRET等信息,或者整个PDF
查看旧发票时,每次都实时生成发票是不行的,因为公司的SIRET居然会是变的!!
- Android实现位图剪切
我们不能总是依赖于BitmapFactory 以下告诉大家怎么从Bitmaqp中截取某一部分创建新的Bitmap 系统会有一个默认png图片:icon.png 可是这个图片中最外层会有白色的 比較讨 ...
- CentOS Kernel Source Install
http://linuxmoz.com/centos-kernel-source-install/
- hadoop每个家庭成员
本文没有提到的原则.谈论hadoop项目周边,它的作用. hadoop这个词已经流行了很多年.大数据的记载会认为hadoop,然后hadoop的作用是什么呢? 官方定义:hadoop是一个开发和执行处 ...