2014 Super Training #9 F A Simple Tree Problem --DFS+线段树
原题: ZOJ 3686 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686
这题本来是一个比较水的线段树,结果一个mark坑了我好几个小时。。哎。太弱。
先DFS这棵树,树形结构转换为线性结构,每个节点有一个第一次遍历的时间和最后一次遍历的时间,之间的时间戳都为子树的时间戳,用线段树更新这段区间即可实现更新子树的效果,用到懒操作节省时间。
坑我的地方: update时,不能写成:tree[rt].mark = 1, 而要写成 tree[rt].mark ^= 1; 因为如果持续update偶数次相当于什么都没做,但是每次update确实是更新了的啊,每次pushdown都会将tree[rt].mark变为0的啊,也就是说tree[rt].mark是不能保持的,所以我搞不懂的是为什么要异或1,而不能直接令等于1,有待向大神请教,如果有看到并知道的仁兄可以指教一下我。
代码:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <algorithm>
- #include <vector>
- using namespace std;
- #define N 100007
- struct node
- {
- int l,r;
- }p[N];
- struct Tree
- {
- int sum,mark;
- }tree[*N];
- int Time;
- vector<int> G[N];
- void pushup(int rt)
- {
- tree[rt].sum = tree[*rt].sum + tree[*rt+].sum;
- }
- void build(int l,int r,int rt)
- {
- tree[rt].sum = tree[rt].mark = ;
- if(l == r)
- return;
- int mid = (l+r)/;
- build(l,mid,*rt);
- build(mid+,r,*rt+);
- pushup(rt);
- }
- void pushdown(int l,int r,int rt)
- {
- if(!tree[rt].mark)
- return;
- int mid = (l+r)/;
- tree[*rt].mark ^= ; //not "tree[2*rt].mark = tree[rt].mark"
- tree[*rt+].mark ^= ;
- tree[*rt].sum = (mid-l+)-tree[*rt].sum;
- tree[*rt+].sum = (r-mid)-tree[*rt+].sum;
- tree[rt].mark = ;
- }
- void update(int l,int r,int aa,int bb,int rt)
- {
- if(aa<=l && bb>=r)
- {
- tree[rt].mark ^= ; //not "tree[rt].mark = 1", 因为偶数次操作相互抵消
- tree[rt].sum = r-l+-tree[rt].sum;
- return;
- }
- pushdown(l,r,rt);
- int mid = (l+r)/;
- if(aa <= mid)
- update(l,mid,aa,bb,*rt);
- if(bb > mid)
- update(mid+,r,aa,bb,*rt+);
- pushup(rt);
- }
- void dfs(int u)
- {
- p[u].l = Time++;
- for(int i=;i<G[u].size();i++)
- dfs(G[u][i]);
- p[u].r = Time++;
- }
- int query(int l,int r,int aa,int bb,int rt)
- {
- if(aa>r || bb<l)
- return ;
- if(aa<=l && bb>=r)
- return tree[rt].sum;
- pushdown(l,r,rt);
- int mid = (l+r)/;
- return query(l,mid,aa,bb,*rt)+query(mid+,r,aa,bb,*rt+);
- }
- int main()
- {
- int n,m,i,j,x;
- char ss[];
- while(scanf("%d%d",&n,&m)!=EOF)
- {
- for(i=;i<=n;i++)
- G[i].clear();
- for(i=;i<=n;i++)
- {
- scanf("%d",&x);
- G[x].push_back(i);
- }
- Time = ;
- dfs();
- build(,*n,);
- while(m--)
- {
- scanf("%s%d",ss,&x);
- if(ss[] == 'o')
- update(,*n,p[x].l,p[x].r,);
- else
- printf("%d\n",query(,*n,p[x].l,p[x].r,)/);
- }
- puts("");
- }
- return ;
- }
2014 Super Training #9 F A Simple Tree Problem --DFS+线段树的更多相关文章
- ZOJ 3686 A Simple Tree Problem(线段树)
Description Given a rooted tree, each node has a boolean (0 or 1) labeled on it. Initially, all the ...
- zoj 3686 A Simple Tree Problem (线段树)
Solution: 根据树的遍历道的时间给树的节点编号,记录下进入节点和退出节点的时间.这个时间区间覆盖了这个节点的所有子树,可以当做连续的区间利用线段树进行操作. /* 线段树 */ #pragma ...
- 2014 Super Training #7 F Power of Fibonacci --数学+逆元+快速幂
原题:ZOJ 3774 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3774 --------------------- ...
- 2014 Super Training #6 F Search in the Wiki --集合取交+暴力
原题: ZOJ 3674 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3674 题意不难理解,很容易想到用暴力,但是无从下 ...
- 2014 Super Training #2 F The Bridges of Kolsberg --DP
原题:UVA 1172 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- 2014 Super Training #1 F Passage 概率DP
原题: HDU 3366 http://acm.hdu.edu.cn/showproblem.php?pid=3366 本来用贪心去做,怎么都WA,后来看网上原来是一个DP题. 首先按P/Q来做排 ...
- 2014 Super Training #10 C Shadow --SPFA/随便搞/DFS
原题: FZU 2169 http://acm.fzu.edu.cn/problem.php?pid=2169 这题貌似有两种解法,DFS和SPFA,但是DFS怎么都RE,SPFA也要用邻接表表示边, ...
- ZOJ 3686 A Simple Tree Problem
A Simple Tree Problem Time Limit: 3 Seconds Memory Limit: 65536 KB Given a rooted tree, each no ...
- BNU 28887——A Simple Tree Problem——————【将多子树转化成线段树+区间更新】
A Simple Tree Problem Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on ZJU. O ...
随机推荐
- (旧)子数涵数·DW——图文混排页面
一.首先,打开Dreamweaver,新建一个的HTML项目. 二.在设计区里,写一些文字,随便写一点(也可以在代码区中的<body>和</body>之间写). 三.插入一张图 ...
- Represent code in math equations
Introduce The article shows a way to use math equations to represent code's logical. Key ideas logic ...
- Docker有什么好处?
Docker背后的想法是创建软件程序可移植的轻量容器,让其可以在任何安装了Docker的机器上运行,而不用关心底层操作系统,类似船舶使用的集装箱,野心勃勃的他们成功了. Docker可以解决虚拟机能够 ...
- [ASP.NET MVC] 使用Bootsnipp样式
[ASP.NET MVC] 使用Bootsnipp样式 前言 在「[ASP.NET MVC] 使用Bootstrap套件」这篇文章中,介绍了如何在Web项目里使用Bootstrap套件,让用户界面更加 ...
- CRM 2013 系统设置新功能一:界面自动保存 及 SDK 中 Xrm.Page.data.entity.save
CRM 2013 界面会自动保存了..在系统设置中默认“是”,如果不需要可以调整. CRM实体记录在新建时会有出现“保存”按钮,非新建状态下,没有“保存”按钮只有“新建”按钮,系统将会自动为你保存最后 ...
- oracle pfile spfile
1.参数文件的定义.作用 oracle数据库通过一系列参数来对数据库进行配置.这些参数是以键-值对的形式来表 示的,如:MAXLOGFILES=50BACKGROUND_DUMP_DEST=C:DUM ...
- java随机生成指定的位数
/** * 获取count个随机数 * @param count 随机数个数 * @return */ public static String game(int count){ StringBuff ...
- Oracle SQL Tips
左连接的同时只输出关联表的一条记录 WITH X AS (SELECT 1 ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL ...
- Ubuntu上安装Apache、MySql和PHP
参考文献: http://developer.51cto.com/art/201110/299303.htm
- android res文件夹下面的 values-v11 、 values-v14
values-v11代表在API 11+的设备上,用该目录下的styles.xml代替res/values/styles.xml values-v14代表在API 14+的设备上,用该目录下的styl ...