CodeForces 877E DFS序+线段树
CodeForces 877E DFS序+线段树
题意
就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身一共有几个灯是亮的。pow x,表示你需要改变x的子树和x本身上的灯的状态。
题解思路
这个题肯定是用DFS序了,为啥?因为树不好操作啊(我也不会啊),使用DFS序可以把树压成一维的一串数,这样就可以使用线段树来进行区间操作了。
话说这个题是我暑假限时训练中做的,看到这个题老开心了,但是让我万万没想到的是,这个题我交了11次才过,太心酸了。
代码实现
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<iostream>
#include<vector>
using namespace std;
const int maxn=2e5+100;
struct node{
int l, r;
int sum;
int lazy;
}t[maxn<<2];
vector<int> g[maxn];
int num[maxn];
int in[maxn], out[maxn], rk[maxn], cnt;
int n, m;
void dfs(int u, int fa) //
{
in[u]=++cnt;//这个是u进去的是时间
rk[cnt]=u; //不要忘了这个,这个是新生成的序列,也就是树被压成一维的那个数列。就是这忘了,害的我好苦。
int len=g[u].size();
for(int i=0; i<len; i++)
{
int v=g[u][i];
if(v==fa) continue;
dfs(v, u);
}
out[u]=cnt;
}
void up(int rt)
{
t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
}
void build(int rt, int l, int r)
{
t[rt].l=l;
t[rt].r=r;
t[rt].sum=0;
t[rt].lazy=0;
if(l==r)
{
t[rt].sum=num[rk[l]]; //这里也不要能错了,很重要。
return ;
}
int mid=(l+r)>>1;
build(rt<<1, l, mid);
build(rt<<1|1, mid+1, r);
up(rt);
}
void down(int rt)
{
if(t[rt].lazy==0) return ;
int ls=rt<<1, rs=rt<<1|1;
t[ls].lazy=!t[ls].lazy;
t[ls].sum=t[ls].r-t[ls].l+1-t[ls].sum;
t[rs].lazy=!t[rs].lazy;
t[rs].sum=t[rs].r-t[rs].l+1-t[rs].sum;
t[rt].lazy=0;
}
void update(int rt, int l, int r)
{
if(l <= t[rt].l && t[rt].r <= r )
{
t[rt].lazy = !t[rt].lazy;
t[rt].sum=t[rt].r-t[rt].l+1-t[rt].sum;
return ;
}
down(rt);
int mid=(t[rt].l+t[rt].r)>>1;
if(l<=mid) update(rt<<1, l, r);
if(r>mid) update(rt<<1|1, l, r);
up(rt);
}
int query(int rt, int l, int r)
{
if(l <= t[rt].l && t[rt].r <= r)
{
return t[rt].sum;
}
int ans=0;
down(rt);
int mid=(t[rt].l+t[rt].r)>>1;
if(l<=mid) ans+=query(rt<<1, l, r);
if(r>mid) ans+=query(rt<<1|1, l, r);
return ans;
}
void init()
{
cnt=0;
for(int i=0; i<=n; i++)
{
g[i].clear();
}
}
int main()
{
scanf("%d", &n);
{
cnt=0;
int x;
string op;
if(n==1)
{
scanf("%d", &x);
scanf("%d" , &m);
while(m--)
{
int tmp;
cin>>op;
scanf("%d", &tmp);
if(op=="get") printf("%d\n", x);
else x=!x;
}
return 0;
}
for(int i=2; i<=n; i++)
{
scanf("%d", &x);
g[x].push_back(i);
g[i].push_back(x);
}
dfs(1, 0);
for(int i=1; i<=n; i++)
{
scanf("%d", &num[i]);
}
build(1, 1, n);
scanf("%d", &m);
for(int i=1; i<=m; i++)
{
cin>>op;
scanf("%d", &x);
if(op=="get")
{
printf("%d\n", query(1, in[x], out[x]));
}
else
{
update(1, in[x], out[x]);
}
}
}
return 0;
}
CodeForces 877E DFS序+线段树的更多相关文章
- Codeforces 396C (DFS序+线段树)
题面 传送门 题目大意: 给定一棵树,每个点都有权值,边的长度均为1,有两种操作 操作1:将节点u的值增加x,并且对于u的子树中的任意一个点v,将它的值增加x-dist(u,v)*k, dist(u, ...
- Codeforces 1110F(DFS序+线段树)
题面 传送门 分析 next_id = 1 id = array of length n filled with -1 visited = array of length n filled with ...
- Codeforces 1132G(dfs序+线段树)
题面 传送门 分析 对于每一个数a[i],找到它后面第一个大于它的数a[p],由p向i连边,最终我们就会得到一个森林,且p是i的父亲.为了方便操作,我们再增加一个虚拟节点n+1,把森林变成树. 由于序 ...
- CodeForces 877E Danil and a Part-time Job(dfs序+线段树)
Danil decided to earn some money, so he had found a part-time job. The interview have went well, so ...
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- Codeforces Round #442 (Div. 2)A,B,C,D,E(STL,dp,贪心,bfs,dfs序+线段树)
A. Alex and broken contest time limit per test 2 seconds memory limit per test 256 megabytes input s ...
- 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 339 Solved: 130[Submit][Status][Discuss] D ...
- BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)
题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
随机推荐
- 35.ES6语法介绍——2019年12月24日
2019年12月24日16:22:24 2019年10月09日12:04:44 1. ES6介绍 1.1 新的 Javascript 语法标准 --2015年6月正式发布 --使用babel语法转换器 ...
- 基于python3环境下搭建Robot Framework 自动化测试框架(一)
大家都知道,Robot Framework 是基于python2 环境 的一套自动化测试工具,据说python 2 到2020年不维护,现在用python 3 的环境搭建Robot Framework ...
- 原创——Nginx基础
Nginx基础 一.Nginx概述: Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx ...
- echart--如何自定义提示框的内容和样式实例
图例的大概样子 具体设置代码为:
- 认识.net Framework
- rk3328设备树学习
一.用到的rk3328好像使用了设备树 设备树我知道的有三种文件类型,dtbs是通过指令make dtbs编译的二进制文件,供内核使用. 基于同样的软件分层设计的思想,由于一个SoC可能对应多个mac ...
- Pandas中的qcut和cut
qcut与cut的主要区别: qcut:传入参数,要将数据分成多少组,即组的个数,具体的组距是由代码计算 cut:传入参数,是分组依据.具体见示例 1.qcut方法,参考链接:http://panda ...
- Android and HTML5 开发手机应用(转载)
作为一个WEB开发者,HTML5让我兴奋,因为它可以将桌面应用程序功能带入浏览器中.但在国内,看着到处横行的IE8版本以下的浏览器,觉得到能大规模使用HTML5技术的那天,还遥遥无期.但面对iOS及A ...
- python字典小知识
字典的小知识dic = {"name": "tom", "age": 23, "price": 110}# 01:提取键 ...
- python-网络编程urllib模块
一.操作网络发送请求 from urllib.request import urlopen #发送请求 from urllib.parse import urlencode #用来把字典形式转 ...