题目链接:点击查看
题意:n个节点,原先都是空的,1,x 让x的所有孩子包括x都变成满的,2,x 让x的所有父辈加上x都变成空的,3,x 询问x这个节点是满的还是空的,满的输出1,空的输出0
题解:对应1操作,我们dfs序一下即可,对于2操作我们用树链剖分来解决,然后直接查询即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+10;
struct node{
int l,r;
int val,laz;
}tree[N<<2];
struct edge{
int to,nex;
}e[N*2];
int n,m;
int val[N];
int head[N],len;
int in[N],out[N],p[N],cnt;
int son[N],s_num[N],fath[N],root[N];
void init()
{
len=cnt=0;
for(int i=1;i<=n;i++)
head[i]=-1;
}
void addedge(int x,int y)
{
e[len].to=y;
e[len].nex=head[x];
head[x]=len++;
}
void dfs1(int u,int fa)
{
s_num[u]=1;
int to,maxx=-1,id=-1;
for(int i=head[u];~i;i=e[i].nex)
{
to=e[i].to;
if(to==fa)continue;
dfs1(to,u);
s_num[u]+=s_num[to];
if(s_num[to]>maxx)
{
maxx=s_num[to];
id=to;
}
}
son[u]=id;
}
void dfs2(int u,int fa,int rt)
{
in[u]=++cnt;
p[cnt]=u;
fath[u]=fa;
root[u]=rt;
if(son[u]!=-1)
{
dfs2(son[u],u,rt);
}
int to;
for(int i=head[u];~i;i=e[i].nex)
{
to=e[i].to;
if(to==fa||to==son[u])continue;
dfs2(to,u,to);
}
out[u]=cnt;
}
void pushdown(int cur)
{
if(tree[cur].laz!=-1)
{
tree[cur<<1].laz=tree[cur].laz;
tree[cur<<1|1].laz=tree[cur].laz;
tree[cur<<1].val=tree[cur].laz;
tree[cur<<1|1].val=tree[cur].laz;
tree[cur].laz=-1;
}
}
void build(int l,int r,int cur)
{
tree[cur].l=l;
tree[cur].r=r;
tree[cur].val=0;
tree[cur].laz=-1;
if(l==r)
{
return;
}
int mid=(r+l)>>1;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
}
void update(int pl,int pr,int cur,int val)
{
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
tree[cur].val=val;
tree[cur].laz=val;
return;
}
pushdown(cur);
if(pl<=tree[cur<<1].r) update(pl,pr,cur<<1,val);
if(pr>=tree[cur<<1|1].l)update(pl,pr,cur<<1|1,val);
}
int query(int pos,int cur)
{
if(tree[cur].l==tree[cur].r)
{
return tree[cur].val;
}
pushdown(cur);
if(pos<=tree[cur<<1].r) return query(pos,cur<<1);
else return query(pos,cur<<1|1);
}
void solve(int x)
{
int f1=root[x];
while(f1!=1)
{
// cout<<in[f1]<<" "<<in[x]<<endl;
update(in[f1],in[x],1,0);
x=fath[x];
f1=root[x];
}
// cout<<in[x]<<endl;
update(1,in[x],1,0);
}
int main()
{
scanf("%d",&n);
init();
int x,y;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
}
dfs1(1,0);
dfs2(1,0,1);
build(1,n,1);
scanf("%d",&m);
int op;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&op,&x);
if(op==1)
{
update(in[x],out[x],1,1);
}
else if(op==2)
{
solve(x);
}
else if(op==3)
{
printf("%d\n",query(in[x],1));
}
}
return 0;
}