ZOJ-3686 A Simple Tree Problem 线段树
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686
题意:给定一颗有根树,每个节点有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=;
const int INF=0x3f3f3f3f;
const int MOD=1e+,STA=;
const LL LNF=1LL<<;
const double EPS=1e-;
const double OO=1e15;
const int dx[]={-,,,};
const int dy[]={,,,-};
const int day[]={,,,,,,,,,,,,};
//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[N],next[N*],e[N*],ra[N],id[N],sum[N],one[N<<],rev[N<<];
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]=;
for(i=first[u];i!=-;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]=;
one[rt<<]=llen-one[rt<<];
one[rt<<|]=rlen-one[rt<<|];
rev[rt<<]^=,rev[rt<<|]^=;
}
} void update(int l,int r,int rt,int L,int R)
{
if(L<=l && r<=R){
rev[rt]^=;
one[rt]=r-l+-one[rt];
return ;
}
int mid=(l+r)>>;
pushdown(rt,mid-l+,r-mid);
if(L<=mid)update(lson,L,R);
if(R>mid)update(rson,L,R);
one[rt]=one[rt<<]+one[rt<<|];
} 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)>>;
pushdown(rt,mid-l+,r-mid);
if(L<=mid)query(lson,L,R);
if(R>mid)query(rson,L,R);
one[rt]=one[rt<<]+one[rt<<|];
} int main()
{
// freopen("in.txt","r",stdin);
int i,j,t;
char op[];
while(~scanf("%d%d",&n,&m))
{
mem(first,-);mt=;
for(i=;i<=n;i++){
scanf("%d",&t);
adde(t,i);
}
cnt=;
dfs(,-);
for(i=;i<=n;i++)id[ra[i]]=i; mem(one,);mem(rev,);
while(m--){
scanf("%s%d",op,&t);
if(op[]=='o'){
update(,n,,id[t],id[t]+sum[t]-);
}
else {
ans=;
query(,n,,id[t],id[t]+sum[t]-);
printf("%d\n",ans);
}
}
putchar('\n');
}
return ;
}
ZOJ-3686 A Simple Tree Problem 线段树的更多相关文章
- ZOJ 3686 A Simple Tree Problem
A Simple Tree Problem Time Limit: 3 Seconds Memory Limit: 65536 KB Given a rooted tree, each no ...
- 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 ...
- bzoj 3489 A simple rmq problem - 线段树
Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直 ...
- hdu 4973 A simple simulation problem. (线段树)
题目链接 题意: 给定n长的序列 m个操作 序列默认为 1, 2, 3···n 操作1:D [l,r] 把[l,r]区间增长 :( 1,2,3,4 进行 D [1,3]变成 1,1,2,2,3,3,4 ...
- BNU 28887——A Simple Tree Problem——————【将多子树转化成线段树+区间更新】
A Simple Tree Problem Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on ZJU. O ...
- 【BZOJ4999】This Problem Is Too Simple!(线段树)
[BZOJ4999]This Problem Is Too Simple!(线段树) 题面 BZOJ 题解 对于每个值,维护一棵线段树就好啦 动态开点,否则空间开不下 剩下的就是很简单的问题啦 当然了 ...
- xtu数据结构 I. A Simple Tree Problem
I. A Simple Tree Problem Time Limit: 3000ms Memory Limit: 65536KB 64-bit integer IO format: %lld ...
- hdu 5274 Dylans loves tree(LCA + 线段树)
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
随机推荐
- An AnnotationConfiguration instance is required to use
An AnnotationConfiguration instance is required to use <mapping class="jebe7282/study/hibern ...
- R语言实战读书笔记(一)R语言介绍
1.3.3 工作空间 getwd():显示当前工作目录 setwd():设置当前工作目录 ls():列出当前工作空间中的对象 rm():删除对象 1.3.4 输入与输出 source():执行脚本
- Android AIDL自动生成Java文件测试
/******************************************************************************** * Android AIDL自动生成 ...
- 8个必备的PHP功能开发 (转)
做过PHP开发的程序员应该清楚,PHP中有很多内置的功能,掌握了它们,可以帮助你在做PHP开发时更加得心应手,本文将分享8个开发必备的PHP功能,个个都非常实用,希望各位PHP开发者能够掌握. 1.传 ...
- yaf框架流程一
资料参考: Yaf是一个C语言编写的PHP框架,以php扩展的形式. 是 laruence(鸟哥) 的作品 laruence 是PHP 开发组成员, PECL 开发者. Yaf, Taint等Pec ...
- Servlet容器的启动(Tomcat为例)
一.容器简介 在tomcat容器等级中,context容器直接管理servlet在容器中的包装类Wrapper,所以Context容器如何运行将直接影响servlet的工作方式. tomcat容器模型 ...
- 戴维·卡梅伦(David William Donald Cameron)经典语录
戴维·威廉·唐纳德·卡梅伦(英语:David William Donald Cameron,1966年10月9日-),汉化译名为甘民乐.现任英国首相.第一财政大臣.公务员事务部部长和保守党党魁,也是英 ...
- github 开源项目
项目地址: https://github.com/Trinea/android-open-project
- MVC-READ5(asp.net web from PK asp.net MVC)
webform: ViewState问题 页面生命周期 不能很好的分解关注点 对HTML操控受限 抽象不完全 可测试性弱
- K2 K2Blackpearl安装步骤详解(服务端)
转:http://www.cnblogs.com/dannyli/archive/2011/11/30/2269485.html 以下是K2 Blackpearl的安装步骤,本人亲测可用哦. 1.安装 ...