题意:一棵树结构上有水,往一个节点加水,那么所有的子节点都会有水,或者排干一个节点的水,那么它的上面的节点都会没水。

用dfs序,数组记录区间内全部有水为1,区间内有没水的点就为0。

倒水:区间更新,排水:单点更新,并更新途中经过的所有点,查询:区间查询。

倒水:区间内所有的点变为有水,就是1,用lazy数组,要下传。

排水:所有节点的dfs序之间的相交只能是包含,并且只被祖先包含。那么在线段树中就将经过的点全部排去。这样祖先节点查询时就为0了,并且无关节点还是有水。不过这样有个BUG,假如开始全有水,如果一个节点排空了立即加水,那么祖先又有水了,实际上是没水,这时将祖先排水就行。

6
2 1
3 1
4 1
4 5
2 6
4
1 1
2 4
1 4
3 1就这。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#include <unordered_set>
#define mkp make_pair
using namespace std;
const double EPS=1e-;
typedef long long lon;
const lon SZ=,SSZ=*SZ,APB=,INF=0x7FFFFFFF,mod=;
lon n,bg[SZ],fn[SZ],cnt,arr[SSZ],lazy[SSZ];
lon pre[SZ];
vector<int> mp[SZ]; void release()
{ } void dfs(int x,int p)
{
bg[x]=++cnt;
pre[x]=p;
for(int i=;i<mp[x].size();++i)
{
int to=mp[x][i];
if(to!=p)
{
dfs(to,x);
}
}
fn[x]=cnt;
} void pushdown(int rt)
{
if(lazy[rt])
{
lazy[rt*]=lazy[rt*+]=;
arr[rt*]=arr[rt*+]=;
lazy[rt]=;
}
} void pushup(int rt)
{
arr[rt]=arr[rt*]*arr[rt*+];
} void update(int ll,int rr,int rt,int ql,int qr)
{
int mid=(ll+rr)/;
pushdown(rt);
if(ql<=ll&&rr<=qr)
{
arr[rt]=;
lazy[rt]=;
return;
}
if(ll>rr)return;
if(ql<=mid)update(ll,mid,rt*,ql,qr);
if(qr>mid)update(mid+,rr,rt*+,ql,qr);
pushup(rt);
} void update(int ll,int rr,int rt,int pos)
{
int mid=(ll+rr)/;
pushdown(rt);
if(ll==rr)
{
arr[rt]=;
return;
}
if(pos<=mid)update(ll,mid,rt*,pos);
else update(mid+,rr,rt*+,pos);
pushup(rt);
} int qry(int ll,int rr,int rt,int ql,int qr)
{
//cout<<" "<<ll<<" "<<rr<<endl;
int mid=(ll+rr)/;
pushdown(rt);
if(ql<=ll&&rr<=qr)
{
return arr[rt];
}
if(ll>rr)return ;
int res1=,res2=;
if(ql<=mid)res1=qry(ll,mid,rt*,ql,qr);
if(qr>mid)res2=qry(mid+,rr,rt*+,ql,qr);
return res1*res2;
} void init()
{
cin>>n;
for(int i=;i<=n-;++i)
{
int a,b;
cin>>a>>b;
mp[a].push_back(b);
mp[b].push_back(a);
}
dfs(,-);
} void work()
{
int qnum;
cin>>qnum;
for(int i=;i<=qnum;++i)
{
int type,x;
cin>>type>>x;
if(type==)
{
if(x!=&&!qry(,cnt,,bg[x],fn[x]))update(,cnt,,bg[pre[x]]);
update(,cnt,,bg[x],fn[x]);
}
else if(type==)
{
update(,cnt,,bg[x]);
}
else
{
//cout<<"3: "<<bg[x]<<" "<<fn[x]<<endl;
cout<<qry(,cnt,,bg[x],fn[x])<<endl;
}
}
} int main()
{
//std::ios::sync_with_stdio(0);
//freopen("d:\\2.txt","r",stdin);
//freopen("d:\\3.txt","w",stdout);
lon casenum;
//cin>>casenum;
//cout<<casenum<<endl;
//for(lon time=1;time<=casenum;++time)
//for(lon time=1;scanf("%d%d",&n,&m)!=EOF;++time)
{
init();
work();
release();
}
return ;
}

codeforces 343d的更多相关文章

  1. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

  2. CodeForces - 343D 树链剖分

    题目链接:http://codeforces.com/problemset/problem/343/D 题意:给定一棵n个n-1条边的树,起初所有节点权值为0,然后m个操作. 1 x:把x为根的子树的 ...

  3. Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...

  4. Codeforces 343D Water Tree 分类: Brush Mode 2014-10-05 14:38 98人阅读 评论(0) 收藏

    Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a res ...

  5. CodeForces 343D 线段树维护dfs序

    给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u ...

  6. Codeforces 343D WaterTree - 线段树, DFS序

    Description Translated by @Nishikino_Maki from Luogu 行吧是我翻的 Mad scientist Mike has constructed a roo ...

  7. codeforces 343D 树剖后odt维护

    子树修改+路径修改+单点查询 树链剖分+区间维护即可 由于只有单点查询,我直接用了odt,复杂度还行 #include<bits/stdc++.h> #define endl '\n' # ...

  8. CodeForces 343D water tree(树链剖分)

    Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a res ...

  9. Codeforces 343D Water Tree

    题意简述 维护一棵树,支持以下操作: 0 v:将以v为跟的子树赋值为1 1 v:将v到根节点的路径赋值为0 2 v:询问v的值 题解思路 树剖+珂朵莉树 代码 #include <set> ...

随机推荐

  1. 前端模板 artTemplate之辅助方法template.helper

    var labelMap = { onlinePayment:{ label:"在线支付", desc:"支持大部分储蓄卡.信用卡及第三方平台支付", name ...

  2. nessus无法访问https://localhost:8834/#/,解决方法。

    之前没弄明白为啥经常访问不了https://localhost:8834/#/,后面才发现是服务关闭了. 首先netstat -an 查看8834是否开启, 直接运行一下nessus目录下的nessu ...

  3. ASP.NET C# 如何在程序中控制IIS服务或应用程序池重启?

    停止IIS服务ServiceController sc = new ServiceController("iisadmin");if(sc.Status==ServiceContr ...

  4. openshift 容器云从入门到崩溃之八《日志聚合》

    日志可以分为两部分 业务日志 业务日志一般是要长期保留的,以供以后有问题随时查询,elk是现在比较流行的日志方案,但是容器日志最好不要落地所以不能把logstash客户端包在容器里面 可以使用logs ...

  5. python_WSGI接口

    WSGI:Web Server Gateway Interface WSGI接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求.我们来看一个最简单的Web版本的“Hello, ...

  6. n皇后问题——关于斜线的编号

    题目大意:在n*n的棋盘中,放置n个皇后(同一行.同一列.同一斜线,只有一个皇后) 这道题是一道非常经典的dfs模板题,同一行.同一列的判断不是很难,但同一斜线有一定的难度,下面给出关于斜线编号的解决 ...

  7. 21 python的魔法方法(转)

    魔法方法 含义   基本的魔法方法 __new__(cls[, ...]) 1. __new__ 是在一个对象实例化的时候所调用的第一个方法2. 它的第一个参数是这个类,其他的参数是用来直接传递给 _ ...

  8. 每天一个Linux命令 10

    文件处理命令:ln命令名称:ln 命令英文原意:link语法: ln -s [原文件] [目标文件] -s 创建软连接功能描述:生成链接文件 #ln -s /etc/issue /tmp/issue. ...

  9. Python+OpenCV图像处理(十五)—— 圆检测

    简介: 1.霍夫圆变换的基本原理和霍夫线变换原理类似,只是点对应的二维极径.极角空间被三维的圆心和半径空间取代.在标准霍夫圆变换中,原图像的边缘图像的任意点对应的经过这个点的所有可能圆在三维空间用圆心 ...

  10. 在python中使用正则表达式

    一.转义符 1.在python中的转义符 (1)\\n与\n的区别 (2)r"\next" 通过r来进行转义 (3)"\\\\d"与"\\d" ...