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'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
随机推荐
- 【Linux】CentOS6上安装Python3.7(config、make、make install)及“No module named '_ctypes'”/pip install时“ssl module in Python is not available.”的解决
1.下载安装包 https://www.python.org/ftp/python/ 该目录下选择所需要的版本进行下载.解压. wget https://www.python.org/ftp/pyth ...
- 3分钟教会你把封装的js公共方法挂载在vue实例原型上
第一步:首先在src文件夹里面创建一个通用js文件夹,然后在创建的文件夹里面创建一个js文件 第二步:const 一个方法,然后通过export暴露出来(在同一个页面可以写多个方法,和暴露多个方法,在 ...
- Linux学习-NFS服务
一.NFS服务相关介绍 1.NFS简介 NFS (Network File System) 网络文件系统,基于内核的文件系统.Sun公司开发,通过使用NFS,用户和程序可以像访问本地文件一样访问远端系 ...
- 解决json不能解析换行问题
今天遇到一个问题,当我读取数据库中某条带换行的数据时,解析错误. 解决方法是在存入数据库时对数据做处理,把换行换成其他字符.代码如下: remark = remark.replace(/\n/g,&q ...
- webpack配置反向代理
devServer: { contentBase: path.resolve(__dirname, "../dev"), compress: true, port: ,//本身的端 ...
- 搭建nginx环境(参考腾讯云实验室)
使用 yum 安装 Nginx: yum install nginx -y 修改 /etc/nginx/conf.d/default.conf,去除对 IPv6 地址的监听,可参考下面的代码示例: s ...
- android中使用Application
在android开发过程中,我们可能存储一些全局的变量,最好在正在app的任何一个activity或者service中都可以访问到,这时我们可以使用application. 我们的一个应用就叫appl ...
- Xcode磁盘空间清理
http://www.iwangke.me/2013/09/09/clean-xcode-to-free-up-disk-space/#jtss-tsina 这个目录下面的文件也可以隔一段儿时间清理一 ...
- React Native商城项目实战08 - 设置“More”界面cell
1.自定义可复用的cell More/CommonCell.js: /** * 自定义可复用的cell */ import React, { Component } from 'react'; imp ...
- DesignWare I2C模块的验证
I2C通信协议主要同一块板上芯片间的通信,因此速度不是很高.SCL为时钟线,SDA为数据线.时钟由主设备发送给从设备,数据可以在两设备间互传. 在测试DW_I2C模块时,如果外面都包了一层,在tb中只 ...