洛谷 U141578 维修电路
题目背景
为了出一套模拟赛赛题,SeawaySeawaySeaway认真钻研了家里的电路。但是,不巧的是,SeawaySeawaySeaway实在太菜了,他把家里的电路弄坏了......
题目描述
所以他要修好这个电路,以免被麻麻打屁屁。SeawaySeawaySeaway细细端详着这套电路,就像之前描述的那样,这套电路被SeawaySeawaySeaway抽象成一棵以1为根元件,含NNN个元件的有根树。每个元件只能输出两种信号:0/10/10/1。现在,这个电路坏了,所以它的所有元件都只能输出000信号。SeawaySeawaySeaway会对整套电路进行MMM次维修,每次维修,他会选择在以下操作中进行一种:
1、将元件xxx和其子树上的所有元件的输出信号改为1信号。
2、将元件xxx到根元件上所有元件的输出信号改为0信号。
3、查询xxx元件的信号种类。
现在SeawaySeawaySeaway聘请你作为他的维修顾问,你能准确无误地回答SeawaySeawaySeaway的每个问题么?
输入格式
第一行一个整数NNN,表示元件数目。接下来的N−1N-1N−1行,每行两个整数。这N−1N-1N−1行描述整个电路的拓扑结构。接下来一行一个整数MMM,表示维修操作的数量。接下来的MMM行,每行两个整数,分别描述操作种类和操作作用的元件xxx。
输出格式
对于每个333号操作,输出0/10/10/1表示你的答案。
命题背景:
emm。。。赶出来的模拟赛。不解释了。
题解:
树剖裸题放T1,真有你的。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e6+7;
struct node{
int l,r,sum,lazy;
}tree[maxn<<2];
int head[maxn],nxt[maxn<<1],to[maxn<<1],tot;
int n,m,x,y;
void add(int x,int y)
{
nxt[++tot]=head[x];
to[tot]=y;
head[x]=tot;
}
int fa[maxn],deep[maxn],id[maxn],val[maxn],size[maxn],son[maxn],top[maxn],cnt;
void dfs1(int x,int f)
{
fa[x]=f;
size[x]=1;
deep[x]=deep[f]+1;
int maxson=-1;
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(y==f)
continue;
dfs1(y,x);
size[x]+=size[y];
if(size[y]>maxson)
{
maxson=size[y];
son[x]=y;
}
}
}
void dfs2(int x,int t)
{
top[x]=t;
id[x]=++cnt;
if(!son[x])
return;
dfs2(son[x],t);
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(y==son[x]||y==fa[x])
continue;
dfs2(y,y);
}
}
void build(int pos,int l,int r)
{
tree[pos].l=l,tree[pos].r=r,tree[pos].lazy=-1;
if(l==r)
return;
int mid=(l+r)>>1;
build(pos<<1,l,mid);
build(pos<<1|1,mid+1,r);
}
void pushdown(int pos)
{
if(tree[pos].lazy!=-1)
{
tree[pos<<1].sum=(tree[pos<<1].r-tree[pos<<1].l+1)*tree[pos].lazy;
tree[pos<<1|1].sum=(tree[pos<<1|1].r-tree[pos<<1|1].l+1)*tree[pos].lazy;
tree[pos<<1].lazy=tree[pos].lazy;
tree[pos<<1|1].lazy=tree[pos].lazy;
tree[pos].lazy=-1;
}
}
void update(int pos,int l,int r,int y)
{
if(tree[pos].l>=l&&tree[pos].r<=r)
{
tree[pos].sum=(tree[pos].r-tree[pos].l+1)*y;
tree[pos].lazy=y;
return;
}
pushdown(pos);
int mid=(tree[pos].l+tree[pos].r)>>1;
if(l<=mid)
update(pos<<1,l,r,y);
if(r>mid)
update(pos<<1|1,l,r,y);
tree[pos].sum=tree[pos<<1].sum+tree[pos<<1|1].sum;
}
int query(int pos,int l,int r)
{
if(tree[pos].l>=l&&tree[pos].r<=r)
return tree[pos].sum;
pushdown(pos);
int mid=(tree[pos].l+tree[pos].r)>>1;
int val=0;
if(l<=mid)
val+=query(pos<<1,l,r);
if(r>mid)
val+=query(pos<<1|1,l,r);
return val;
}
void upd_chain(int x,int y,int k)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]])
swap(x,y);
update(1,id[top[x]],id[x],k);
x=fa[top[x]];
}
if(deep[x]<deep[y])
swap(x,y);
update(1,id[y],id[x],k);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
scanf("%d",&m);
int opt,x;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&opt,&x);
if(opt==1)
update(1,id[x],id[x]+size[x]-1,1);
else if(opt==2)
upd_chain(x,1,0);
else
printf("%d
",query(1,id[x],id[x]));
}
return 0;
}