Codeforces Round #200 (Div. 1) D. Water Tree(dfs序+线段树+思维)
发布日期:2021-05-08 15:18:19 浏览次数:21 分类:精选文章

本文共 1358 字,大约阅读时间需要 4 分钟。

在这里插入图片描述
在这里插入图片描述
题意:给定一棵树,初始树中所有数都是0,然后有三个操作,1、将v和它的子树变1;2、将v和它的所有祖先节点变0,3、输出v的值。
思路:1和3都很容易解决,用dfs序+线段树就可以了,但2不好处理,看大佬好像都是用树剖,可惜弱鸡不会QAQ,还有一种很妙的方法,我们对于2可以单点更新,线段树来维护区间最小值,,在1操作前将v的父亲节点设为0就行(类似于差分思想),然后查询的时候如果v和它的子树里有一个0的话答案就是0了,否则都是1。

#include
using namespace std;typedef long long ll;const int maxn=5e5+5;vector
g[maxn];struct node{ int l,r,w,lazy;}tree[maxn<<2];int cnt=0,in[maxn],out[maxn],pre[maxn];void dfs(int u,int fa){ pre[u]=fa; in[u]=++cnt; for(int to:g[u]) { if(to==fa) continue; dfs(to,u); } out[u]=cnt;}void pushup(int x){ tree[x].w=min(tree[x<<1].w,tree[x<<1|1].w);}void pushdown(int x){ if(tree[x].lazy) { tree[x<<1].w=tree[x<<1].lazy=tree[x].lazy; tree[x<<1|1].w=tree[x<<1|1].lazy=tree[x].lazy; tree[x].lazy=0; }}void build(int l,int r,int x){ tree[x].l=l;tree[x].r=r; if(l==r){ tree[x].w=0; return ; } int mid=(l+r)>>1; build(l,mid,x<<1); build(mid+1,r,x<<1|1); pushup(x);}void update(int x,int l,int r,int val){ if(l<=tree[x].l&&tree[x].r<=r) { tree[x].w=tree[x].lazy=val; return ; } pushdown(x); int mid=(tree[x].l+tree[x].r)>>1; if(l<=mid) update(x<<1,l,r,val); if(mid
>1; if(l<=mid) ans=query(x<<1,l,r); if(mid
1) update(1,in[pre[t]],in[pre[t]],0); update(1,in[t],out[t],1); } else if(op==2) update(1,in[t],in[t],0); else printf("%d\n",query(1,in[t],out[t])==0?0:1); }}
上一篇:Codeforces Round #305 (Div. 1) B. Mike and Feet(单调栈)
下一篇:Codeforces Round #149 (Div. 2) C. King's Path(bfs)

发表评论

最新留言

不错!
[***.144.177.141]2025年04月02日 07时04分45秒