Codeforces 343D Water Tree(DFS序 + 线段树)
2016-07-18 15:13
483 查看
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1、把某结点以及其各个祖先值设为0、询问某结点的值。
对于第一个操作就是经典的DFS序+线段树了。而对于第二个操作,考虑再维护一个域表示各个结点为根的子树是否有进行第二个操作,如果有那么该结点应该就要是0;而在进行第一个操作前,看一下子树是否有进行第二个操作,如果有就整个标记成没有并把标记上传,让该结点的父亲结点标记成进行了第二个操作。
对于第一个操作就是经典的DFS序+线段树了。而对于第二个操作,考虑再维护一个域表示各个结点为根的子树是否有进行第二个操作,如果有那么该结点应该就要是0;而在进行第一个操作前,看一下子树是否有进行第二个操作,如果有就整个标记成没有并把标记上传,让该结点的父亲结点标记成进行了第二个操作。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXN 555555 struct Edge{ int v,next; }edge[MAXN<<1]; int NE,head[MAXN]; void addEdge(int u,int v){ edge[NE].v=v; edge[NE].next=head[u]; head[u]=NE++; } int l[MAXN],r[MAXN],par[MAXN],dfn; void dfs(int u,int fa){ l[u]=++dfn; for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(v==fa) continue; par[v]=u; dfs(v,u); } r[u]=dfn; } int x,y,z,N; bool tree[MAXN<<2],down[MAXN<<2],up[MAXN<<2]; void updateUp(int i,int j,int k){ if(x<=i && j<=y){ up[k]=z; return; } if(up[k]==0){ up[k<<1]=0; up[k<<1|1]=0; } int mid=i+j>>1; if(x<=mid) updateUp(i,mid,k<<1); if(y>mid) updateUp(mid+1,j,k<<1|1); up[k]=up[k<<1]|up[k<<1|1]; } bool queryUp(int i,int j,int k){ if(x<=i && j<=y){ return up[k]; } if(up[k]==0){ up[k<<1]=0; up[k<<1|1]=0; } int mid=i+j>>1; bool res=0; if(x<=mid) res|=queryUp(i,mid,k<<1); if(y>mid) res|=queryUp(mid+1,j,k<<1|1); return res; } void update(int i,int j,int k){ if(x<=i && j<=y){ tree[k]=z; down[k]=z; return; } if(down[k]==1){ tree[k<<1]=1; tree[k<<1|1]=1; down[k<<1]=1; down[k<<1|1]=1; down[k]=0; } int mid=i+j>>1; if(x<=mid) update(i,mid,k<<1); if(y>mid) update(mid+1,j,k<<1|1); } bool query(int i,int j,int k){ if(i==j){ return tree[k]; } if(down[k]==1){ tree[k<<1]=1; tree[k<<1|1]=1; down[k<<1]=1; down[k<<1|1]=1; down[k]=0; } int mid=i+j>>1; if(x<=mid) return query(i,mid,k<<1); else query(mid+1,j,k<<1|1); } int main(){ int n,q,a,b; scanf("%d",&n); memset(head,-1,sizeof(head)); for(int i=1; i<n; ++i){ scanf("%d%d",&a,&b); addEdge(a,b); addEdge(b,a); } for(N=1; N<n; N<<=1); dfs(1,1); scanf("%d",&q); while(q--){ scanf("%d%d",&a,&b); if(a==1){ x=l[b]; y=r[b]; if(queryUp(1,N,1)){ z=0; updateUp(1,N,1); if(b!=1){ x=l[par[b]]; y=l[par[b]]; z=1; updateUp(1,N,1); } } x=l[b]; y=r[b]; z=1; update(1,N,1); }else if(a==2){ x=l[b]; y=l[b]; z=1; updateUp(1,N,1); }else if(a==3){ x=l[b]; y=r[b]; if(queryUp(1,N,1)){ puts("0"); }else{ x=l[b]; y=l[b]; printf("%d\n",query(1,N,1)); } } } return 0; }
相关文章推荐
- hadoop2.7【单节点】单机、伪分布、分布式安装指导
- 接入支付宝出现交易订单处理失败,请稍后再试(ALI64)的错误
- redis持久化
- rgba(0,0,0,0.6)IE不支持解决方法
- CentOS 6.4 下安装vsftpd
- 【HDU5722 BestCoder 2nd AnniversaryE】【线段树 矩形面积并】Jewelry 多少区间内至少存在一数恰好出现tim次
- M**tar CTS环境搭建
- 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
- C 语言快速排序实例代码
- ansible使用过程中随记
- SQL语句里怎么获得当前年份(MySQL数据库)
- jQueryUI中Datepicker(日历)插件的介绍和使用
- 构建数据库
- 谈谈项目和需求
- jquery easyui datagrid 添加超链接
- 通过Data Binding为RecyclerView打造通用Adapter
- hdu 5719 Arrange (dp 递推 排列组合)
- codeforces366 语文题
- 史上最全IO框架四(转换流)
- Redis学习笔记一:redis简介及安装使用