您的位置:首页 > 其它

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

2016-07-18 15:13 483 查看
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1、把某结点以及其各个祖先值设为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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: