ZOJ-3686 A Simple Tree Problem 线段树
2014-03-03 17:38
435 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686
题意:给定一颗有根树,每个节点有0和1两种值。有两种操作:o a操作,把以a为根节点的子树的权值全部取反;q a操作,求以a为根节点的子树权值为1的节点个数。
先求出树的先序遍历结果,并且记录每颗子树的节点个数,然后就可以用线段树维护了。。
题意:给定一颗有根树,每个节点有0和1两种值。有两种操作:o a操作,把以a为根节点的子树的权值全部取反;q a操作,求以a为根节点的子树权值为1的节点个数。
先求出树的先序遍历结果,并且记录每颗子树的节点个数,然后就可以用线段树维护了。。
//STATUS:C++_AC_240MS_6524KB #include <functional> #include <algorithm> #include <iostream> //#include <ext/rope> #include <fstream> #include <sstream> #include <iomanip> #include <numeric> #include <cstring> #include <cassert> #include <cstdio> #include <string> #include <vector> #include <bitset> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <list> #include <set> #include <map> using namespace std; //#pragma comment(linker,"/STACK:102400000,102400000") //using namespace __gnu_cxx; //define #define pii pair<int,int> #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define PI acos(-1.0) //typedef typedef long long LL; typedef unsigned long long ULL; //const const int N=100010; const int INF=0x3f3f3f3f; const int MOD=1e+7,STA=8000010; const LL LNF=1LL<<60; const double EPS=1e-8; const double OO=1e15; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //Daily Use ... inline int sign(double x){return (x>EPS)-(x<-EPS);} template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;} template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;} template<class T> inline T lcm(T a,T b,T d){return a/d*b;} template<class T> inline T Min(T a,T b){return a<b?a:b;} template<class T> inline T Max(T a,T b){return a>b?a:b;} template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);} template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);} template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));} template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));} //End int first ,next[N*2],e[N*2],ra ,id ,sum ,one[N<<2],rev[N<<2]; int n,m,mt,cnt,ans; void adde(int a,int b) { e[mt]=b; next[mt]=first[a],first[a]=mt++; e[mt]=a; next[mt]=first[b],first[b]=mt++; } int dfs(int u,int fa) { ra[cnt++]=u; int i,j; sum[u]=1; for(i=first[u];i!=-1;i=next[i]){ if(e[i]==fa)continue; sum[u]+=dfs(e[i],u); } return sum[u]; } void pushdown(int rt,int llen,int rlen) { if(rev[rt]){ rev[rt]=0; one[rt<<1]=llen-one[rt<<1]; one[rt<<1|1]=rlen-one[rt<<1|1]; rev[rt<<1]^=1,rev[rt<<1|1]^=1; } } void update(int l,int r,int rt,int L,int R) { if(L<=l && r<=R){ rev[rt]^=1; one[rt]=r-l+1-one[rt]; return ; } int mid=(l+r)>>1; pushdown(rt,mid-l+1,r-mid); if(L<=mid)update(lson,L,R); if(R>mid)update(rson,L,R); one[rt]=one[rt<<1]+one[rt<<1|1]; } void query(int l,int r,int rt,int L,int R) { if(L<=l && r<=R){ ans+=one[rt]; return ; } int mid=(l+r)>>1; pushdown(rt,mid-l+1,r-mid); if(L<=mid)query(lson,L,R); if(R>mid)query(rson,L,R); one[rt]=one[rt<<1]+one[rt<<1|1]; } int main() { // freopen("in.txt","r",stdin); int i,j,t; char op[2]; while(~scanf("%d%d",&n,&m)) { mem(first,-1);mt=0; for(i=2;i<=n;i++){ scanf("%d",&t); adde(t,i); } cnt=1; dfs(1,-1); for(i=1;i<=n;i++)id[ra[i]]=i; mem(one,0);mem(rev,0); while(m--){ scanf("%s%d",op,&t); if(op[0]=='o'){ update(1,n,1,id[t],id[t]+sum[t]-1); } else { ans=0; query(1,n,1,id[t],id[t]+sum[t]-1); printf("%d\n",ans); } } putchar('\n'); } return 0; }
相关文章推荐
- 函数指针数组与不定参数的应用
- 个梵蒂冈福蓉
- 单例模式 模板类和非模板类实现
- linux下使用gcc编译Nate Robin的OpenGL教程
- Java IO 理论笔记
- 对付DNF硬件断点的NtGetContextThread的写法
- SQLServer性能优化之SQL语句性能测试
- 利用dmesg和addr2line来重现bug
- php 语法一
- Android 手动显示和隐藏软键盘 (转)
- Struct还是Class?
- vc++ 创建进程
- Hinernate一对双向映射
- C语言经典算法100例-020-小球自由下落问题
- HTTP协议 (二) 基本认证
- 愿
- 集合转数组的toArray()和toArray(T[] a)方法
- bespoke_百度百科
- ASP.NET MVC3入门教程之第一个WEB应用程序
- zz 聊聊并发(五)