您的位置:首页 > 其它

zoj 3686 A Simple Tree Problem

2013-05-16 20:57 330 查看
题意就是给你一颗树。初始时每个节点的值都为0,现在有两种操作,‘o’操作是将以节点i为根的子树的每个节点取反,即0变1,1变0.‘q’操作是求以节点i为根的子树中1的个数。

方法主要是给每个节点分配一个区间,是这个区间的节点都是它的子节点。然后就是线段树的经典操作啦。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 100005
struct node{
int num,c;
}setree[maxn<<2];
struct{
int y,next;
}ee[maxn<<1];
struct op{
int l,r;
}mes[maxn];
int t,link[maxn],cnt;
void insert(int a,int b)
{
ee[++t].y=b;
ee[t].next=link[a];
link[a]=t;
}
void dfs(int root,int father)
{
int tmp=cnt;
mes[root].l=cnt;
for(int i=link[root];i;i=ee[i].next){
if(ee[i].y!=father){
dfs(ee[i].y,root);
}
}
if(tmp==cnt){
mes[root].r=cnt++;
return;
}
mes[root].r=cnt++;
}
void build(int l,int r,int rt)
{
setree[rt].num=0;
setree[rt].c=0;
if(l==r)
return;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void pushdown(int rt,int len)
{
if(setree[rt].c){
setree[rt<<1].c=1-setree[rt<<1].c;
setree[rt<<1].num=len-len/2-setree[rt<<1].num;
setree[rt<<1|1].c=1-setree[rt<<1|1].c;
setree[rt<<1|1].num=len/2-setree[rt<<1|1].num;
setree[rt].c=0;
}
}
void pushup(int rt)
{
setree[rt].num=setree[rt<<1].num+setree[rt<<1|1].num;
}
void update(int l,int r,int rt,int L,int R)
{
if(L<=l&&r<=R){
setree[rt].c=1-setree[rt].c;
setree[rt].num=r-l+1-setree[rt].num;
return;
}
int m=(l+r)>>1;
pushdown(rt,r-l+1);
if(L<=m)
update(lson,L,R);
if(R>m)
update(rson,L,R);
pushup(rt);
}
int query(int l,int r,int rt,int L,int R)
{
if(L<=l&&r<=R)
return setree[rt].num;
int m=(l+r)>>1;
pushdown(rt,r-l+1);
int ans=0;
if(L<=m)
ans+=query(lson,L,R);
if(R>m)
ans+=query(rson,L,R);
return ans;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)){
memset(link,0,sizeof(link));
t=0;
for(int i=2;i<=n;i++){
int a;
scanf("%d",&a);
insert(a,i);
insert(i,a);
}
cnt=1;
dfs(1,1);
build(1,n,1);
while(m--){
char s[5];
int a;
scanf("%s%d",s,&a);
if(s[0]=='o')
update(1,n,1,mes[a].l,mes[a].r);
else
printf("%d\n",query(1,n,1,mes[a].l,mes[a].r));
}
printf("\n");
}
return 0;
}


AC Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: