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 ...
随机推荐
- hihoCoder 1043 完全背包 (dp)
http://hihocoder.com/problemset/problem/1043 动态转移方程 :for v=cost..V f[v]=max(f[v],f[v-c[i]]+w[i]); #i ...
- pyhton与json,Xml
对简单数据类型的encoding 和 decoding: 使用简单的json.dumps方法对简单数据类型进行编码,例如: 1 2 3 4 5 6 import json obj = [[1,2, ...
- lightOJ 1366 Pair of Touching Circles(统计矩形内相切圆对)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1366 题意:给出一个矩形,在内部画两个圆A和B使得AB都完全在矩形内且AB相切且AB的 ...
- Client-Side UI Automation Provider - WinForm Sample
Client-Side UI Automation Provider - WinForm Sample 2014-09-15 源代码 目录 引用程序集实现提供程序接口分发客户端提供程序注册和配置客户 ...
- 修改tomcat小猫图标
网站放到网上去了,不喜欢大家访问的时候可以看到tomcat的小猫图标.今天在网上搜了搜,总结一下收藏了. 1.直接找个16*16的ico图片.放到tomcat/root下,取个名叫favicon.ic ...
- android 安装 出现Android Native Development Tools不能安装
Software being installed: Android Native Development Tools 20.0.0.v201206242043-391819 (com.android. ...
- 最小生成树之Kruskal
模板题,学习一下最小生成树的Kruskal算法 对于一个连通网(连通带权图,假定每条边上的权均为大于零的实数)来说,每棵树的权(即树中所有边的权值总和)也可能不同 具有权最小的生成树称为最小生成树 生 ...
- HDU 1372 (搜索方向稍有改变) Knight Moves
其实手写模拟一个队列也挺简单的,尤其是熟练以后. 尼玛,这题欺负我不懂国际象棋,后来百度了下,国际象棋里骑士的走法就是中国象棋里面的马 所以搜索就有八个方向 对了注意初始化标记数组的时候,不要把起点标 ...
- Volley : "参数param:{ inoutNo:inoutNo ,whcode:’’}
private void fuzzySearch() { mRequestQueue = Volley.newRequestQueue(getActivity()); String str = Sha ...
- Phpstorm Xdebug Web程序调试
平时调试php程序的时候,可以通过在代码中添加var_dump等函数来实现简单的断点调试. 下面介绍另一种方法,通过Phpstorm和Xdebug来进行调试. 1.下载Xdebug 这个是官网下载地址 ...