CF343D Water Tree
题目翻译(摘自洛谷)
疯狂科学家Mike培养了一颗有根树,由n个节点组成。每个节点是一个要么装满水要么为空的贮水容器. 树的节点用1~n编号,其中根节点为1.对于每个节点的容器,其子节点的容器均在这一容器下方,并且每个节点都由一根可以向下流水的管道与其子节点连接. Mike想要对这棵树做以下操作:
1将节点v注满水. 这样v和其子节点都会充满水.
2将节点v置空. 这样v及其祖先节点(从v到根节点的路径)都会被置空.
3查询当前节点v是否充满水.
初始时,所有节点都为空. Mike已经制定好了他的操作顺序. 在对树进行实验前,他决定先模拟一下操作. 请你帮助Mike得出他操作后的结果.
思路
裸树链剖分,区间修改,单点查询。
#include<iostream>
#include<cstdio>
using namespace std;
const int N=;
int n,cnt,dcnt,hd[N];
struct edge
{
int to,nxt;
}v[*N];
struct node
{
int fa,son,sz,dep,tp,s,e;
}tr[N];
struct segtree
{
int l,r,stat,tag;
}st[*N];
void addedge(int x,int y)
{
v[++cnt].to=y;
v[cnt].nxt=hd[x];
hd[x]=cnt;
}
void dfs1(int u)
{
tr[u].sz=;
for(int i=hd[u];i;i=v[i].nxt)
if(v[i].to!=tr[u].fa)
{
tr[v[i].to].fa=u;
tr[v[i].to].dep=tr[u].dep+;
dfs1(v[i].to);
tr[u].sz+=tr[v[i].to].sz;
if(tr[v[i].to].sz>tr[tr[u].son].sz)
tr[u].son=v[i].to;
}
}
void dfs2(int u,int top)
{
tr[u].tp=top;
tr[u].s=++dcnt;
if(tr[u].son)
{
dfs2(tr[u].son,top);
for(int i=hd[u];i;i=v[i].nxt)
if(v[i].to!=tr[u].fa&&v[i].to!=tr[u].son)
dfs2(v[i].to,v[i].to);
}
tr[u].e=dcnt;
}
void build(int num,int l,int r)
{
st[num].l=l,st[num].r=r;
st[num].tag=-;
if(l==r)
return ;
int mid=(l+r)/;
build(*num,l,mid),build(*num+,mid+,r);
}
void pushdown(int num)
{
if(st[num].tag!=-)
{
if(st[num].l!=st[num].r)
{
st[*num].stat=st[*num+].stat=st[num].tag;
st[*num].tag=st[*num+].tag=st[num].tag;
}
st[num].tag=-;
}
}
void change(int num,int l,int r,int z)
{
if(l>st[num].r||r<st[num].l)
return ;
if(st[num].l>=l&&st[num].r<=r)
{
st[num].tag=st[num].stat=z;
return ;
}
pushdown(num);
change(*num,l,r,z),change(*num+,l,r,z);
}
int query(int num,int x)
{
if(st[num].l>x||st[num].r<x)
return ;
if(st[num].l==st[num].r)
return st[num].stat;
pushdown(num);
return query(*num,x)+query(*num+,x);
}
void fnd(int x)
{
int f1=tr[x].tp;
while(f1!=)
{
change(,tr[f1].s,tr[x].s,);
x=tr[f1].fa,f1=tr[x].tp;
}
change(,,tr[x].s,);
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n-;i++)
{
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y),addedge(y,x);
}
dfs1();
dfs2(,);
build(,,n);
int q,x,y;
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&x,&y);
switch(x)
{
case :
change(,tr[y].s,tr[y].e,);
break;
case :
fnd(y);
break;
case :
printf("%d\n",query(,tr[y].s));
break;
}
}
return ;
}
CF343D Water Tree的更多相关文章
- 【题解】Luogu CF343D Water Tree
原题传送门:CF343D Water Tree 这道题要用树链剖分,我博客里有对树链剖分的详细介绍 这明显是弱智题 树剖套珂朵莉树多简单啊 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自 ...
- CF343D Water Tree 树链剖分
问题描述 LG-CF343D 题解 树剖,线段树维护0-1序列 yzhang:用珂朵莉树维护多好 \(\mathrm{Code}\) #include<bits/stdc++.h> usi ...
- Codeforces Round #200 (Div. 1) D Water Tree 树链剖分 or dfs序
Water Tree 给出一棵树,有三种操作: 1 x:把以x为子树的节点全部置为1 2 x:把x以及他的所有祖先全部置为0 3 x:询问节点x的值 分析: 昨晚看完题,马上想到直接树链剖分,在记录时 ...
- Codeforces Round #200 (Div. 1)D. Water Tree dfs序
D. Water Tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/343/problem/ ...
- Codeforces Round #200 (Div. 1) D. Water Tree 树链剖分+线段树
D. Water Tree time limit per test 4 seconds memory limit per test 256 megabytes input standard input ...
- Water Tree(树链剖分+dfs时间戳)
Water Tree http://codeforces.com/problemset/problem/343/D time limit per test 4 seconds memory limit ...
- xtu summer individual 6 F - Water Tree
Water Tree Time Limit: 4000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Orig ...
- 343D/Codeforces Round #200 (Div. 1) D. Water Tree dfs序+数据结构
D. Water Tree Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each ...
- Water Tree CodeForces 343D 树链剖分+线段树
Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...
随机推荐
- 详解JSOUP的Select选择器语法
本文参考:JSOUP中文文档 问题 你想使用类似于CSS或jQuery的语法来查找和操作元素. 方法 可以使用Element.select(String selector) 和 Elements.se ...
- 【C#复习总结】细说匿名方法
1 前言 本系列会将[委托] [匿名方法][Lambda表达式] [泛型委托] [表达式树] [事件]等基础知识总结一下.(本人小白一枚,有错误的地方希望大佬指正) 系类1:细说委托 系类2:细说匿名 ...
- Python-类的封装
1:封装数据 将数据隐藏起来这不是目的.隐藏起来然后对外提供操作该数据的接口,然后我们可以在接口附加上对该数据操作的限制,以此完成对数据属性操作的严格控制. class Teacher: def __ ...
- 在k-means或kNN,我们是用欧氏距离来计算最近的邻居之间的距离。为什么不用曼哈顿距离?
曼哈顿距离只计算水平或垂直距离,有维度的限制.另一方面,欧氏距离可用于任何空间的距离计算问题. 因为,数据点可以存在于任何空间,欧氏距离是更可行的选择.例如:想象一下国际象棋棋盘,象或车所 做的移动是 ...
- elasticsearch判断索引是否存在
一.判断索引是否存在 指定索引名,判断指定的索引是否存在集群中 /** * 判断指定的索引名是否存在 * @param indexName 索引名 * @return 存在:true; 不存在:fal ...
- python札记
进制转换 num = "0011"v = int(num, base=16)print(v)2->16
- ERP & CRM
ERP流程_百度百科https://baike.baidu.com/item/ERP%E6%B5%81%E7%A8%8B/8099248 CRM_百度百科https://baike.baidu.com ...
- 解决多人开发时使用window.onload的覆盖问题
通用型小函数:解决多人开发时,同时使用window.onload事件所出现的后面的window.onload函数覆盖前面一个window.onload函数的问题. function addLoadEv ...
- java.lang包【Object类】
基本描述: (1)Object类位于java.lang包中,java.lang包包含着Java最基础和核心的类,在编译时会自动导入: (2)Object类是所有Java类的祖先.每个类都使用 Obje ...
- SQLSERVER sa 用户密码修改的方法
本次驱动人生病毒的收获 . 偷懒总会有报应. . 应用(数据库或者是web应用nginx等.)都不要使用最高级别权限用户来使用 虽然这样的环境问题最少. . 密码还是需要定期更换的,虽然有成本,但是也 ...