原题: 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+线段树的更多相关文章

  1. 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 ...

  2. zoj 3686 A Simple Tree Problem (线段树)

    Solution: 根据树的遍历道的时间给树的节点编号,记录下进入节点和退出节点的时间.这个时间区间覆盖了这个节点的所有子树,可以当做连续的区间利用线段树进行操作. /* 线段树 */ #pragma ...

  3. 2014 Super Training #7 F Power of Fibonacci --数学+逆元+快速幂

    原题:ZOJ 3774  http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3774 --------------------- ...

  4. 2014 Super Training #6 F Search in the Wiki --集合取交+暴力

    原题: ZOJ 3674 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3674 题意不难理解,很容易想到用暴力,但是无从下 ...

  5. 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_ ...

  6. 2014 Super Training #1 F Passage 概率DP

    原题: HDU 3366   http://acm.hdu.edu.cn/showproblem.php?pid=3366 本来用贪心去做,怎么都WA,后来看网上原来是一个DP题. 首先按P/Q来做排 ...

  7. 2014 Super Training #10 C Shadow --SPFA/随便搞/DFS

    原题: FZU 2169 http://acm.fzu.edu.cn/problem.php?pid=2169 这题貌似有两种解法,DFS和SPFA,但是DFS怎么都RE,SPFA也要用邻接表表示边, ...

  8. ZOJ 3686 A Simple Tree Problem

    A Simple Tree Problem Time Limit: 3 Seconds      Memory Limit: 65536 KB Given a rooted tree, each no ...

  9. BNU 28887——A Simple Tree Problem——————【将多子树转化成线段树+区间更新】

    A Simple Tree Problem Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on ZJU. O ...

随机推荐

  1. mybatis中#和$符号的区别

    mybatis做为一个轻量级ORM框架在许多项目中使用,因其简单的入门受到了广大开发者的热爱.在近期项目中再做一个相关的开发,碰到了#.$符号这样的问题,之前没怎么注意过,通过学习之后,有了点感悟,分 ...

  2. 自定义View_1_关于View,ViewGroup的测量和绘制流程

    自定义View(1) ------ 关于View,ViewGroup的测量和绘制流程 在Android当中,自定义控件属于比较高级的知识体系,今天我们就一起研究研究关于自定义View的那点事,看看它到 ...

  3. webpack学习(入门基础)

    webpack的学习webpack是什么?1:加载模块(将JS.sass/less.图片等作为模块来处理使用) 2:进行打包 webpack的优势?1:webpack以commonJS(JS的规范)的 ...

  4. HTML <map> 标签-创建带有可点击区域的图像映射

    定义和用法 定义一个客户端图像映射.图像映射(image-map)指带有可点击区域的一幅图像. 所有主流浏览器都支持 <map> 标签. 注释:area 元素永远嵌套在 map 元素内部. ...

  5. SharePoint 2013 中自定义WCF服务

    在使用SharePoint2013的时候,如果其他客户端 API 的组合不足,可以通过自定义 Web 服务扩展 SharePoint.默认情况下,SharePoint 2013 不仅支持创建自定义 A ...

  6. Sharepoint学习笔记—习题系列--70-573习题解析 -(Q73-Q76)

    Question 73You create a Web Part that calls a function named longCall.You discover that longCall tak ...

  7. ListView的addHeaderView()方法相关问题

    使用listView.addHeaderView(view) 可以在 listView 上方添加一个view视图 ,使listView和这个view连接在一起 效果上看上去是一个整体 一般用于上拉刷新 ...

  8. Python基础(9)--正则表达式

    正则表达式是一个很有用的工具,可处理复杂的字符匹配和替换工作.在Python中内置了一个re模块以支持正则表达式. 正则表达式有两种基本的操作,分别是匹配和替换. 匹配就是在一个文本字符串中搜索匹配一 ...

  9. NSEnumerator

    NSEnumerator 基本理解 NSEnumerator是一个抽象类,它没有用来创建实例的公共接口.而NSArray,NSDictionary,NSSet可以通过相关方法返回一个实例 可以使用它的 ...

  10. ListView嵌套出现的问题

    项目中一个列表子项中也需要用到列表,这就不由得使我想到ListView的嵌套,其实这个东西想想也只是复杂了一点,并没有什么难的地方,可是却依然在这里狠狠滴栽个跟头.问题出在子列表动态展开的操作上.可能 ...