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 ...
随机推荐
- rails权限管理—devise+cancan+rolify
使用devise.cancan和rolify组件建立用户权限模型的说明. devise:负责用户注册.登录.退出.找回密码等操作.细节参考devise on github cancan:负责角色建立. ...
- 自定义数据校验(4)---demo3---bai
工具类:CharUtil package com.etc.util; import java.util.regex.Pattern; public class CharUtil { public st ...
- X509 文件扩展名
编码 (也用于扩展名) .DER = 扩展名DER用于二进制DER编码的证书.这些证书也可以用CER或者CRT作为扩展名.比较合适的说法是“我有一个DER编码的证书”,而不是“我有一个DER证书”. ...
- iOS 模块分解— Runtime
相信对于从事开发人员来说 runtime 这个名称都不陌生,就像我起初只知道「 runtime 叫运行时 」,后来知道 runtime 同样可以像 KVC 一样访问私有成员变量,还有「 给类动态添加属 ...
- django之admin组件
一.面向对象复习 1.类的继承 class Base(object): def __init__(self,val): self.val = val def func(self): self.test ...
- Ajax笔记(一)
Ajax三步骤: Asynchronous Javascript And XML 1.运用HTML和CSS实现页面,表达信息: 2.运用XMLHttpRequest和web服务器进行数据的异步交换: ...
- day17-jdbc 5.url介绍
url用于标识数据库的位置,用于标识找哪个数据库. 总结:url是路径,其实就是确定是哪个数据库.用来确定我用的是哪一个数据库,并且通知我这个Connection或者是这个DriverManager获 ...
- [bzoj2460] [BeiJing2011]元素(线性基+贪心)
题目大意: 有一些矿石,每个矿石有一个a和一个b值,要求选出一些矿石,b的和最大且不存在某个矿石子集它们的a的异或和为0. 解题关键:对魔力进行由大到小排序,依次加入线性基,统计即可. #includ ...
- 【总结整理】JS的继承
参考阮一峰的文章:http://javascript.ruanyifeng.com/oop/inheritance.html#toc4 function Shape() { this.x = 0; t ...
- Luogu 3302 [SDOI2013]森林
BZOJ 3123 丑陋的常数,BZOJ 19968ms 卡过. 感觉几个思想都挺经典但是挺套路的. 先考虑不连边的情况怎么做,区间第$k$小,想到主席树,每一个结点维护它到根的前缀和,这样子每一次查 ...