\(\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序的更多相关文章

  1. CodeForces 343D 线段树维护dfs序

    给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u ...

  2. P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA

    \(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...

  3. codeforces 877 E. Danil and a Part-time Job(线段树(dfs序))

    题目链接:http://codeforces.com/contest/877/problem/E 题解:显然一看就感觉要么树链剖分要么线段树+dfs序,题目要求的操作显然用线段树+dfs序就可以实现. ...

  4. 【HIHOCODER 1576】 子树中的最小权值(线段树维护DFS序)

    描述 给定一棵N个节点的树,编号1~N.其中1号节点是根,并且第i个节点的权值是Vi. 针对这棵树,小Hi会询问小Ho一系列问题.每次小Hi会指定一个节点x,询问小Ho以x为根的子树中,最小的权值是多 ...

  5. bzoj 3779: 重组病毒【LCT+线段树维护dfs序】

    %.8lf会WA!!%.8lf会WA!!%.8lf会WA!!要%.10lf!! 和4817有点像,但是更复杂. 首先对于操作一"在编号为x的计算机中植入病毒的一个新变种,在植入一个新变种时, ...

  6. BZOJ 4817 [SDOI2017]树点涂色 (LCT+线段树维护dfs序)

    题目大意:略 涂色方式明显符合$LCT$里$access$操作的性质,相同颜色的节点在一条深度递增的链上 用$LCT$维护一个树上集合就好 因为它维护了树上集合,所以它别的啥都干不了了 发现树是静态的 ...

  7. 2018.11.01 NOIP训练 图论(线段树+倍增+dfs序)

    传送门 一道挺妙的题. 对于询问点(u,v),如右图所示,我们可以发现存在一个点m在u->v的路径中,m子树的点到u是最近的,m子树外到v是最近的.其中dis(u,m)=(dis(u,v)-1) ...

  8. 线段树(dfs序建树加区间更新和单点查询)

    题目链接:https://cn.vjudge.net/contest/66989#problem/J 记录一下这道折磨了我一天的题,.... 具体思路: 具体关系可通过dfs序建树,但是注意,在更新以 ...

  9. CF620E New Year Tree 状压+线段树(+dfs序?)

    借用学长的活:60种颜色是突破口(我咋不知道QAQ) 好像这几道都是线段树+dfs序??于是你可以把60种颜色压进一个long long 里,然后向上合并的时候与一下(太妙了~) 所以记得开long ...

随机推荐

  1. 基于OpenCV的火焰检测(三)——HSI颜色判据

    上文向大家介绍了如何用最简单的RGB判据来初步提取火焰区域,现在我要给大家分享的是一种更加直观的判据--HSI判据. 为什么说HSI判据是更加直观的判据呢?老规矩,先介绍一下HSI色彩模型: HSI颜 ...

  2. 反射+属性标签 通用Excel导入导

    在做通用导入导出的时候,最关键的应该就是实体导出导入的顺序了,但是编译器在编译的时候又无法自定义属性编译的顺序,所以需要一个自定义的特性标签来指定实体类导出的顺序,然后通过自定义的比较器将属性排序 因 ...

  3. Linux系统下Oracle执行SQL脚本后中文出现乱码解决方法

    先确认Oracle的字符集,sqlplus登录Oracle后执行语句:   [sql] select userenv('language') from dual; 返回值例如:AMERICAN_AME ...

  4. OpenGL 着色器 03

    着色器(shader)是运行在GPU上小程序. 也是一种非常独立的程序,它们之间不能相互通信:它们之间唯一的沟通只有通过输入和输出. 着色器的开头总是要声明版本,接着是输入和输出变量,uniform和 ...

  5. 【272】ArcPy处理数据

    参考:ArcPy 函数列表(按字母顺序) 参考:在arcgis上用python脚本(arcpy)做数据批处理 1. 导入 ArcPy,定义 Workspace >>> import ...

  6. eclipse 中使用 GreenUML 和 AmasterasUML 自动生成类图

    Green UML和AmaterasUML 两种 一.安装方法: 1.都是先安装GEF 通过eclipse-> install new software安装GEF的网址: http://down ...

  7. 【android】关于自己实现adapter后gridview中item无法被选中的解决方法

    有时候,自己继承实现了baseadapter将其赋给gridview之后,gridview会十分奇怪的无法选中内部的item. 经过仔细研究,我发现是在继承的时候多复写了几个方法,解决方法就是,只保留 ...

  8. Luogu 4409 [ZJOI2006]皇帝的烦恼

    BZOJ 1863 lyd口中的夹B递推. 挺妙的解法. 第一个感觉是找到一个最大的相邻的$a_i + a_{i - 1}$就可以了,但是这个想法大概只对了一半,一半的意思是说只有在$n$为偶数的时候 ...

  9. Luogu 2467 [SDOI2010]地精部落

    挺有意思的题. 优质题解: https://www.luogu.org/blog/user55639/solution-p2467 题意为求长度为n,取值为$[1, n]$的波动序列的个数. 首先需要 ...

  10. Entity Framework Tutorial Basics(33):Spatial Data type support in Entity Framework 5.0

    Spatial Data type support in Entity Framework 5.0 MS SQL Server 2008 introduced two spatial data typ ...