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 ...
随机推荐
- web.xml中classpath表示什么样的路径
首先 classpath是指 WEB-INF文件夹下的classes目录 解释classes含义: 1.存放各种资源配置文件 eg.init.properties log4j.properties ...
- jenkins学习 02 jenkins安装与配置
1: Jenkins安装 在最简单的情况下,Jenkins 只需要两个步骤: (1)下载最新的版本(一个 WAR 文件).Jenkins官方网址: http://Jenkins-ci.org/ (2 ...
- 读取XML文件的指定节点的值 并转换为Item
cmb_State_Send.ItemsSource = null; XmlDocument doc = new XmlDocument(); doc.Load("D:\\模板\\Works ...
- IT求职经验分享
本来这些东西应该早点写出来,之前由于一些事情的顾虑迟迟没有发表下笔整理并发表出来.最近及接下来的日子是校招找工作的关键时期,结合自己之前找暑期实习的过程及笔试面试经历(主要是三家,腾讯.360.绿盟科 ...
- 2.《Spring学习笔记-MVC》系列文章,讲解返回json数据的文章共有3篇,分别为:
转自:https://www.cnblogs.com/ssslinppp/p/4528892.html 个人认为,使用@ResponseBody方式来实现json数据的返回比较方便,推荐使用. 摘要 ...
- docker 笔记(4) Dockerfile 常用的指令
下面列出了 Dockerfile 中最常用的指令,完整列表和说明可参看官方文档. FROM指定 base 镜像. MAINTAINER设置镜像的作者,可以是任意字符串. COPY将文件从 build ...
- Webrtc服务器搭建<转>
http://blog.csdn.net/zqf_office/article/details/49851209
- madplay的使用方法
管理madplay的主程序,包括播放,暂停播放,恢复播放,停止播放 system("madplay north.mp3 &");//利用system函数调用madplay播 ...
- session详解&和cookie的区别
session简介 1. 定义 session用来保存会话数据, 将数据保存到服务器中. 2. 作用 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),一个浏览器独占一 ...
- android手势(gesture)
需要实现两个接口,OnTouchListener ,OnGestureListener 在接口方法中实现各种事件 详见:http://www.cnblogs.com/JczmDeveloper/p/3 ...