ZOJ 3686 线段树
来源:互联网 发布:starbound mac 汉化 编辑:程序博客网 时间:2024/05/18 12:34
思路:给定一个树结构,每变化一个点其子树上的点都变,我们可以先深搜一次,给每个点编号,然后每个点能影响的点的编号是连续的一段,这样就把树结构转化为线性的,每个点对应于一个区间。之后就是线段树了。
#include<iostream>#include<cstdio>#include<cstring>using namespace std;struct node{ int s,e;}p[400005];struct nnode{ int l,r,c,s;}t[800005];int fst[400005],next[400005],node[400005],en;int n,m;int cnt;void init(){ en=0; cnt=0; memset(fst,-1,sizeof(fst));}void add(int u,int v){ next[en]=fst[u]; fst[u]=en; node[en]=v; en++;}void build(int ll,int rr,int rot){ t[rot].l=ll; t[rot].r=rr; t[rot].s=0; t[rot].c=0; if(ll==rr) { return ; } int mid=(ll+rr)/2; build(ll,mid,rot<<1); build(mid+1,rr,rot<<1|1);}void dfs(int u){ p[u].s=++cnt; for(int i=fst[u];i!=-1;i=next[i]) { dfs(node[i]); } p[u].e=cnt;}void update(int ll,int rr,int rot){ if(t[rot].l==ll&&t[rot].r==rr) { t[rot].c=(t[rot].c^1); t[rot].s=t[rot].r-t[rot].l+1-t[rot].s; } else { if(t[rot].c==1) { t[rot<<1].c=(t[rot<<1].c^1); t[rot<<1].s=(t[rot<<1].r-t[rot<<1].l+1-t[rot<<1].s); t[rot<<1|1].c=(t[rot<<1|1].c^1); t[rot<<1|1].s=(t[rot<<1|1].r-t[rot<<1|1].l+1-t[rot<<1|1].s); t[rot].c=0; } int mid=(t[rot].l+t[rot].r)/2; if(rr<=mid)update(ll,rr,rot<<1); else if(ll>mid)update(ll,rr,rot<<1|1); else { update(ll,mid,rot<<1); update(mid+1,rr,rot<<1|1); } t[rot].s=t[rot<<1].s+t[rot<<1|1].s; }}int query(int ll,int rr,int rot){ if(t[rot].l==ll&&t[rot].r==rr)return t[rot].s; else { if(t[rot].c==1) { t[rot<<1].c=(t[rot<<1].c^1); t[rot<<1].s=(t[rot<<1].r-t[rot<<1].l+1-t[rot<<1].s); t[rot<<1|1].c=(t[rot<<1|1].c^1); t[rot<<1|1].s=(t[rot<<1|1].r-t[rot<<1|1].l+1-t[rot<<1|1].s); t[rot].c=0; } int mid=(t[rot].l+t[rot].r)/2; if(rr<=mid)return query(ll,rr,rot<<1); else if(ll>mid)return query(ll,rr,rot<<1|1); else { return query(ll,mid,rot<<1)+query(mid+1,rr,rot<<1|1); } }}int main(){ int u; char str[10]; while(scanf("%d%d",&n,&m)!=EOF) { init(); for(int i=2;i<=n;i++) { scanf("%d",&u); add(u,i); } dfs(1); build(1,n,1); while(m--) { scanf("%s%d",str,&u); if(str[0]=='o') { update(p[u].s,p[u].e,1); } else if(str[0]=='q') { cout<<query(p[u].s,p[u].e,1)<<endl; } } cout<<endl; } return 0;}
- ZOJ 3686 线段树
- ZOJ 3686 后序遍历线段树
- zoj 1610 线段树
- zoj 1610 线段树
- zoj 3635 线段树
- zoj 3724 线段树
- ZOJ 3635 线段树
- zoj 3299 线段树
- ZOJ 3635 线段树
- 线段树 ZOJ 3574
- ZOJ 3299 线段树
- ZOJ 3772 线段树
- ZOJ 1610 线段树
- zoj 1610 线段树
- ZOJ 3324 Machine(线段树)
- zoj 3540 线段树笔记
- ZOJ 2900 Icecream(线段树)
- ZOJ 3279 Ants(线段树)
- 文件上传 Smartupload 和 FileUpload
- Error applying BeanValidation relational constraints错误的解决方案
- C++面试题(二)——自己实现一个String类
- C语言4位数逆序(改)
- PHP empty() & isset()
- ZOJ 3686 线段树
- PushNotification教程–客户端到服务器(PHP)一条龙服务
- 上海云计算培训——Cloud Essential云计算精要认证培训 云计算技术 云计算概念
- synchronized浅析
- c里面使用libcurl库实现发送post并获取post到的内容
- Ie6 Ie7 双倍padding问题
- Hadoop的十大应用领域 云计算是什么 云计算技术 云计算基础 云计算概念 云计算平台
- iBaties的简单入门案例
- qt界面 “父—子”类继承,及析构关系