对线段树的区间更新有了初步的了解。。。

A Simple Tree Problem


Time Limit: 3 Seconds      Memory Limit: 65536 KB

Given a rooted tree, each node has a boolean (0 or 1) labeled on it. Initially, all the labels are 0.

We define this kind of operation: given a subtree, negate all its labels.

And we want to query the numbers of 1's of a subtree.

Input

Multiple test cases.

First line, two integer N and M, denoting the numbers of nodes and numbers of operations and queries.(1<=N<=100000, 1<=M<=10000)

Then a line with N-1 integers, denoting the parent of node 2..N. Root is node 1.

Then M lines, each line are in the format "o node" or "q node", denoting we want to operate or query on the subtree with root of a certain node.

Output

For each query, output an integer in a line.

Output a blank line after each test case.

Sample Input

3 2
1 1
o 2
q 1

Sample Output

1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <queue>
#include <sstream>
#include <iostream>
using namespace std;
#define INF 0x3fffffff
#define N 100100 int n,m;
struct node
{
int to,next;
}edge[*N]; struct node1
{
int b,d,mid;
int flag,sum;
}tnode[*N]; int cnt,pre[N];
int savex[N],savey[N];
int id; // 线段树的区间更新初步了解! void add_edge(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=pre[u];
pre[u]=cnt++;
} void dfs(int s,int path)
{
int tmp;
++id;
tmp=id;
for(int p=pre[s];p!=-;p=edge[p].next)
{
int v=edge[p].to;
if(v!=path)
{
dfs(v,s);
}
}
savex[s]=tmp;
savey[s]=id;
} void built(int b,int d,int s)
{
tnode[s].b=b;
tnode[s].d=d;
tnode[s].mid=(b+d)/;
tnode[s].sum=;
tnode[s].flag=;
if(b==d) return ;
built(b,tnode[s].mid,*s);
built(tnode[s].mid+,d,*s+);
} void insert(int b,int d,int s)
{
if(tnode[s].b==b&&tnode[s].d==d)
{
tnode[s].flag^=;
tnode[s].sum=(d-b+) - tnode[s].sum;
return ;
}
if(tnode[s].flag!=)
{
tnode[s].flag=;
tnode[*s].flag^=;
tnode[*s].sum=(tnode[*s].d-tnode[*s].b+)-tnode[*s].sum; tnode[*s+].flag^=;
tnode[*s+].sum=(tnode[*s+].d-tnode[*s+].b+)-tnode[*s+].sum;
}
if(tnode[s].mid>=d)
insert(b,d,*s);
else if(tnode[s].mid+<=b)
insert(b,d,*s+);
else
{
insert(b,tnode[s].mid,*s);
insert(tnode[s].mid+,d,*s+);
}
tnode[s].sum=tnode[*s].sum+tnode[*s+].sum;//用up,和down就更好理解
} //这样就不需要放回了,更简单了... int find(int b,int d,int s)
{
if(tnode[s].b==b&&tnode[s].d==d)
{
return tnode[s].sum;
}
if(tnode[s].flag!=)
{
tnode[s].flag=;
tnode[*s].flag^=;
tnode[*s].sum=(tnode[*s].d-tnode[*s].b+)-tnode[*s].sum; tnode[*s+].flag^=;
tnode[*s+].sum=(tnode[*s+].d-tnode[*s+].b+)-tnode[*s+].sum;
}
if(tnode[s].mid>=d)
return find(b,d,s*);
else if(tnode[s].mid+<=b)
return find(b,d,*s+);
else return find(b,tnode[s].mid,s*)+find(tnode[s].mid+,d,*s+);
} int main()
{
//freopen("//home//chen//Desktop//ACM//in.text","r",stdin);
//freopen("//home//chen//Desktop//ACM//out.text","w",stdout);
while(scanf("%d%d",&n,&m)!=EOF)
{
cnt=;
id=;
memset(pre,-,sizeof(pre));
for(int i=;i<=n;i++)
{
int tmp;
scanf("%d",&tmp);
add_edge(i,tmp);
add_edge(tmp,i);
}
dfs(,);
///////////////
built(,n,);
for(int i=;i<m;i++)
{
char sel;
int tmp;
cin>>sel;
scanf("%d",&tmp);
if(sel=='o')
{
insert(savex[tmp],savey[tmp],);
}
else
{
printf("%d\n",find(savex[tmp],savey[tmp],));
}
}
printf("\n");
}
return ;
}

zoj3686(线段树的区间更新)的更多相关文章

  1. hdu 1556:Color the ball(线段树,区间更新,经典题)

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  2. hdu 1698:Just a Hook(线段树,区间更新)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. UVA 12436-Rip Van Winkle's Code(线段树的区间更新)

    题意: long long data[250001]; void A( int st, int nd ) { for( int i = st; i \le nd; i++ ) data[i] = da ...

  4. hdu1698线段树的区间更新区间查询

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  5. HDU 1556 Color the ball(线段树:区间更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=1556 题意: N个气球,每次[a,b]之间的气球涂一次色,统计每个气球涂色的次数. 思路: 这道题目用树状数组和 ...

  6. Color the ball (线段树的区间更新问题)

    N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色.但 ...

  7. ZOJ 2301 Color the Ball 线段树(区间更新+离散化)

    Color the Ball Time Limit: 2 Seconds      Memory Limit: 65536 KB There are infinite balls in a line ...

  8. 线段树离散化+区间更新——cf1179C好题

    绝对是很好的题 把问题转化成当第i个询问的答案是数值x时是否可行 要判断值x是否可行,只要再将问题转化成a数组里>=x的值数量是否严格大于b数组里的>=x的值 那么线段树叶子结点维护对于值 ...

  9. hdu 3397 Sequence operation(线段树:区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给你一个长度为n的0,1序列,支持下列五种操作, 操作0(0 a b):将a到b这个区间的 ...

随机推荐

  1. redis骚操作

    1.批量删除key redis-cli -h 127.0.0.1 -p 6379 -n 2 -a sdongpo123 keys '*form_id*' | xargs redis-cli -h 12 ...

  2. C#位操作

    一.原码与补码 在计算机系统中,数值一律用补码来存储(表示).主要原因:使用补码,可以将符号位和其他位统一处理:同时减法也可按加法来处理.另外,两个补码表示的数相加时,如果最高位(符号位)有进位,则进 ...

  3. unity, editorWindow lose data when enter play mode

    我写了个editorWindow,其中有个成员变量m_x,在创建editorWindow的时候为m_x赋的值,而在editorWindow的OnGUI里把m_x显示出来. 当我开着这个editorWi ...

  4. atitit.spring hibernate的事务机制 spring不能保存对象的解决

    atitit.spring hibernate的事务机制 spring不能保存对象的解决 sessionFactory.openSession() 不能..log黑头马sql语言.. sessionF ...

  5. 32位嵌入式微处理器(processor)一览

    32位嵌入式微处理器(processor)一览 由于嵌入式系统的专用型与定制性,与全球PC市场不同,没有一种微处理器或者微处理器公司可以主导嵌入式系统.本文分析了当前市场上主流的一些32位嵌入式微处理 ...

  6. Ubuntu 文件文件夹查看权限和设置权限

    ubuntu下查看权限的命令为: ls -l filename ls -ld folder ubuntu下设置权限的命令为: 一共有10位数 其中: 最前面那个 - 代表的是类型 中间那三个 rw- ...

  7. 基于jQuery实现文字倾斜显示代码

    这是一款基于jQuery实现文字倾斜显示,这是一款基于jQuery实现的超酷动态文字显示效果.适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗. ...

  8. [config]关于make *config

    最近在编译uboot和kernel,二者的编译都有make *_defconfig的用法,而以前都是make menuconfig然后再make, 对于现在这种用法还不太了解,网上查了下,有人给出 如 ...

  9. js监听文本框变化事件

    用js有两种写法: 法一: <!DOCTYPE HTMl> <html> <head> <title> new document </title& ...

  10. json datatable互转(真正能用的-原创)

    网上有不少的转换类 可是不全 或者有错误 我现在贴一个 js 和C# 互转代码 希望能帮到需要的童鞋 首先C#转成 json /// <summary>         /// DataT ...