CF877E Danil and a Part-time Job 线段树维护dfs序
\(\color{#0066ff}{题目描述}\)
有一棵 n 个点的树,根结点为 1 号点,每个点的权值都是 1 或 0
共有 m 次操作,操作分为两种
get 询问一个点 x 的子树里有多少个 1
pow 将一个点 x 的子树中所有节点取反
对于每个 get 给出答案
\(\color{#0066ff}{输入格式}\)
第一行一个整数 n
第二行共 n−1 个整数,第 i 个数 \(x_i\) 表示 \(x_i\) 是 i+1 的父亲,
第三行给出每个点的初始权值
第四行一个整数 m
接下来 m 行为操作类型和位置
\(\color{#0066ff}{输出格式}\)
对于每个 get 给出答案
\(\color{#0066ff}{输入样例}\)
4
1 1 1
1 0 0 1
9
get 1
get 2
get 3
get 4
pow 1
get 1
get 2
get 3
get 4
\(\color{#0066ff}{输出样例}\)
2
0
0
1
2
1
1
0
\(\color{#0066ff}{数据范围与提示}\)
\(1\leq n \leq 200000,1\leq q\leq 200000\)
\(\color{#0066ff}{题解}\)
线段树维护dfs序
同一子树内dfs序连续
线段树上修改查询即可
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define _ 0
#define LL long long
#ifndef olinr
inline char getc()
{
static char buf[100001],*p1=buf,*p2=buf;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100001,stdin),p1==p2)? EOF:*p1++;
}
#else
#define getc() getchar()
#endif
inline LL in()
{
LL x=0,f=1; char ch;
while(!isdigit(ch=getc()))(ch=='-')&&(f=-f);
while(isdigit(ch)) x=x*10+(ch^48),ch=getc();
return x*f;
}
const int max=205005;
int val[max],dfn[max],redfn[max],siz[max];
class SGT
{
private:
struct node
{
int l,r;
int val;
node* ch[2];
bool tag;
node(int l,int r,int val,int tag):l(l),r(r),val(val),tag(tag){}
void upd() {val=ch[0]->val+ch[1]->val;}
int mid() {return (l+r)>>1;}
int siz() {return r-l+1;}
void dwn()
{
if(!tag) return;
ch[0]->val=ch[0]->siz()-ch[0]->val;
ch[1]->val=ch[1]->siz()-ch[1]->val;
ch[0]->tag^=1;
ch[1]->tag^=1;
tag=0;
}
};
typedef node* nod;
public:
nod root;
void build(nod &o,int l,int r)
{
o=new node(l,r,0,0);
if(l==r) return (void)(o->val=val[redfn[l]]);
build(o->ch[0],l,o->mid());
build(o->ch[1],o->mid()+1,r);
o->upd();
}
void lazy(nod o,int l,int r)
{
if(o->r<l||o->l>r) return;
if(l<=o->l&&o->r<=r)
{
o->tag^=1;
o->val=o->siz()-o->val;
return;
}
o->dwn();
lazy(o->ch[0],l,r),lazy(o->ch[1],l,r);
o->upd();
}
int query(nod o,int l,int r)
{
if(o->r<l||o->l>r) return 0;
if(l<=o->l&&o->r<=r) return o->val;
o->dwn();
return query(o->ch[0],l,r)+query(o->ch[1],l,r);
}
}s;
struct node
{
int to;
node *nxt;
node(int to,node *nxt):to(to),nxt(nxt){}
};
typedef node* nod;
nod head[max];
int cnt;
void add(int from,int to)
{
nod t=new node(to,head[from]);
head[from]=t;
}
void dfs(int x,int f)
{
siz[x]=1;
dfn[x]=++cnt;
redfn[cnt]=x;
for(nod i=head[x];i;i=i->nxt)
if(i->to!=f) dfs(i->to,x),siz[x]+=siz[i->to];
}
int n,m;
int main()
{
n=in(); int x;
for(int i=1;i<=n-1;i++) x=in(),add(x,i+1),add(i+1,x);
for(int i=1;i<=n;i++) val[i]=in();
dfs(1,0);
s.build(s.root,1,n);
m=in();
char ch;
while(m--)
{
while(!isalpha(ch=getc()));
x=in();
if(ch=='g') printf("%d\n",s.query(s.root,dfn[x],dfn[x]+siz[x]-1));
else s.lazy(s.root,dfn[x],dfn[x]+siz[x]-1);
}
return 0;
}
CF877E Danil and a Part-time Job 线段树维护dfs序的更多相关文章
- CodeForces 343D 线段树维护dfs序
给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u ...
- P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA
\(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...
- codeforces 877 E. Danil and a Part-time Job(线段树(dfs序))
题目链接:http://codeforces.com/contest/877/problem/E 题解:显然一看就感觉要么树链剖分要么线段树+dfs序,题目要求的操作显然用线段树+dfs序就可以实现. ...
- 【HIHOCODER 1576】 子树中的最小权值(线段树维护DFS序)
描述 给定一棵N个节点的树,编号1~N.其中1号节点是根,并且第i个节点的权值是Vi. 针对这棵树,小Hi会询问小Ho一系列问题.每次小Hi会指定一个节点x,询问小Ho以x为根的子树中,最小的权值是多 ...
- bzoj 3779: 重组病毒【LCT+线段树维护dfs序】
%.8lf会WA!!%.8lf会WA!!%.8lf会WA!!要%.10lf!! 和4817有点像,但是更复杂. 首先对于操作一"在编号为x的计算机中植入病毒的一个新变种,在植入一个新变种时, ...
- BZOJ 4817 [SDOI2017]树点涂色 (LCT+线段树维护dfs序)
题目大意:略 涂色方式明显符合$LCT$里$access$操作的性质,相同颜色的节点在一条深度递增的链上 用$LCT$维护一个树上集合就好 因为它维护了树上集合,所以它别的啥都干不了了 发现树是静态的 ...
- 2018.11.01 NOIP训练 图论(线段树+倍增+dfs序)
传送门 一道挺妙的题. 对于询问点(u,v),如右图所示,我们可以发现存在一个点m在u->v的路径中,m子树的点到u是最近的,m子树外到v是最近的.其中dis(u,m)=(dis(u,v)-1) ...
- 线段树(dfs序建树加区间更新和单点查询)
题目链接:https://cn.vjudge.net/contest/66989#problem/J 记录一下这道折磨了我一天的题,.... 具体思路: 具体关系可通过dfs序建树,但是注意,在更新以 ...
- CF620E New Year Tree 状压+线段树(+dfs序?)
借用学长的活:60种颜色是突破口(我咋不知道QAQ) 好像这几道都是线段树+dfs序??于是你可以把60种颜色压进一个long long 里,然后向上合并的时候与一下(太妙了~) 所以记得开long ...
随机推荐
- Redis codis 搭建测试
codis Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有明显的区别,有部分命令支持 Codis ...
- C#理解泛型(源代码)及 default(T)
1.类型不安全.且代码无法遍历重用的源代码. 2.泛型源代码 源代码下载: http://files.cnblogs.com/files/qqhfeng/ConsoleApplication1.rar
- 最全SDWebImage-3.8版本源码阅读详解
一.前言 SDWebImage,非常友好的网络图片加载第三方框架,在GitHub中已经获得了15000++的star,链接地址:https://github.com/rs/SDWebImage 本人分 ...
- GCD详细用法
一.延迟执行 1.介绍 第一种方法,该方法在那个线程调用,那么run就在哪个线程执行(当前线程),通常是主线程. [self performSelector:@selector(run) withOb ...
- js中的控制结构for-in语句
var arr=['赵','钱','孙','李']; for(var i=0;i<arr.length;i++){ console.log(arr[i]); } var obj={ name:' ...
- NLTK词性标注解释
1. CC Coordinating conjunction 连接词2. CD Cardinal number 基数词3. DT Determin ...
- DPDK内存管理(1)(转)
1 前言 DPDK将利用hugepage预留的物理内存统一的组织管理起来,然后以库的方式对外提供使用的接口.下图展示了DPDK中内存有关的模块的相互关系. rte_eal 是统一 ...
- Luogu 4409 [ZJOI2006]皇帝的烦恼
BZOJ 1863 lyd口中的夹B递推. 挺妙的解法. 第一个感觉是找到一个最大的相邻的$a_i + a_{i - 1}$就可以了,但是这个想法大概只对了一半,一半的意思是说只有在$n$为偶数的时候 ...
- Python程序设计1——基础知识
1 Python脚本设计简介 1.1 输出"Hello World" 和一般的语言一样,运行python程序有两种方式,一种是GUI交互式命令,一种是通过脚本文件,前者适合小型简单 ...
- 树莓派研究笔记(6)-- Lakka模拟游戏机
我发现lakka的支持的游戏平台特别多,包括国产的OrangePI,真是太棒了.我们可以用这个来打造一个全功能模拟器平台.(删除线部分为Orange PI 测试成功内容,但在树莓派上无需那些操作) 访 ...