[Codeforces 877E] Danil and a Part-time Job
[题目链接]
https://codeforces.com/contest/877/problem/E
[算法]
首先求出这棵树的DFS序
一棵子树的DFS序为连续的一段 , 根据这个性质 , 用线段树维护区间中1的个数即可
时间复杂度 : O(NlogN)
[代码]
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + ;
typedef long long ll;
typedef long double ld; struct edge
{
int to , nxt;
} e[MAXN << ]; int n , q , timer , tot;
int val[MAXN] , l[MAXN] , r[MAXN] , dfn[MAXN] , size[MAXN] , head[MAXN] , loc[MAXN] , par[MAXN]; struct Segment_Tree
{
struct Node
{
int l , r , cnt;
bool tag;
} a[MAXN << ];
inline void update(int index)
{
a[index].cnt = a[index << ].cnt + a[index << | ].cnt;
}
inline void build(int index , int l , int r)
{
a[index].l = l , a[index].r = r;
a[index].tag = false;
if (l == r)
{
a[index].cnt = (val[loc[l]] == );
return;
}
int mid = (l + r) >> ;
build(index << , l , mid);
build(index << | , mid + , r);
update(index);
}
inline void pushdown(int index)
{
int l = a[index].l , r = a[index].r;
int mid = (l + r) >> ;
if (a[index].tag)
{
a[index << ].cnt = (mid - l + ) - a[index << ].cnt;
a[index << | ].cnt = (r - mid) - a[index << | ].cnt;
a[index << ].tag ^= ;
a[index << | ].tag ^= ;
a[index].tag = false;
}
}
inline void modify(int index , int l , int r)
{
if (a[index].l == l && a[index].r == r)
{
a[index].cnt = (r - l + ) - a[index].cnt;
a[index].tag ^= ;
return;
}
pushdown(index);
int mid = (a[index].l + a[index].r) >> ;
if (mid >= r) modify(index << , l , r);
else if (mid + <= l) modify(index << | , l , r);
else
{
modify(index << , l , mid);
modify(index << | , mid + , r);
}
update(index);
}
inline int query(int index , int l , int r)
{
if (a[index].l == l && a[index].r == r)
return a[index].cnt;
pushdown(index);
int mid = (a[index].l + a[index].r) >> ;
if (mid >= r) return query(index << , l , r);
else if (mid + <= l) return query(index << | , l , r);
else return query(index << , l , mid) + query(index << | , mid + , r);
}
} SGT; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void addedge(int u , int v)
{
++tot;
e[tot] = (edge){v , head[u]};
head[u] = tot;
}
inline void dfs(int u)
{
l[u] = dfn[u] = ++timer;
loc[timer] = u;
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == par[u]) continue;
dfs(v);
}
r[u] = timer;
} int main()
{ scanf("%d" , &n);
for (int i = ; i <= n; i++)
{
scanf("%d" , &par[i]);
addedge(par[i] , i);
}
for (int i = ; i <= n; i++) scanf("%d" , &val[i]);
dfs();
SGT.build( , , n);
scanf("%d" , &q);
while (q--)
{
char type[];
scanf("%s" , type);
if (type[] == 'p')
{
int u;
scanf("%d" , &u);
SGT.modify( , l[u] , r[u]);
} else
{
int u;
scanf("%d" , &u);
printf("%d\n" , SGT.query( , l[u] , r[u]));
}
} return ; }
[Codeforces 877E] Danil and a Part-time Job的更多相关文章
- Codeforces 877E - Danil and a Part-time Job(dfs序+线段树)
877E - Danil and a Part-time Job 思路:dfs序+线段树 dfs序:http://blog.csdn.net/qq_24489717/article/details/5 ...
- 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 ...
- Codeforces 877E Danil and a Part-time Job(dfs序 + 线段树)
题目链接 Danil and a Part-time Job 题意 给出一系列询问或者修改操作 $pow$ $x$表示把以$x$为根的子树的所有结点的状态取反($0$变$1$,$1$变$0$ ...
- Codeforces 877E - Danil and a Part-time Job 线段树+dfs序
给一个有根树,1e5个节点,每个节点有权值0/.1,1e5操作:1.将一个点的子树上所有点权值取反2.查询一个点的子树的权值和 题解: 先深搜整颗树,用dfs序建立每个点对应的区间,等于把树拍扁成 ...
- CodeForces 877E DFS序+线段树
CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...
- codeforces 877e
E. Danil and a Part-time Job time limit per test 2 seconds memory limit per test 256 megabytes input ...
- Codeforces Round #877 (Div. 2) E. Danil and a Part-time Job
E. Danil and a Part-time Job 题目链接:http://codeforces.com/contest/877/problem/E time limit per test2 s ...
- Codeforces Round #442 (Div. 2) Danil and a Part-time Job
http://codeforces.com/contest/877/problem/E 真的菜的不行,自己敲一个模板,到处都是问题.哎 #include <bits/stdc++.h> u ...
- codeforces 877 E. Danil and a Part-time Job(线段树(dfs序))
题目链接:http://codeforces.com/contest/877/problem/E 题解:显然一看就感觉要么树链剖分要么线段树+dfs序,题目要求的操作显然用线段树+dfs序就可以实现. ...
随机推荐
- Exchange 2013 Database Move to New Partition
建议不要删除默认数据库,可以通过修改默认数据库名称.路径等实现您的需求. 客戶:The HK Anti-Cancer Society. 要求:遷移數據庫(01)到新分區,實際是遷移成為數據庫(05) ...
- C中的预编译编译链接
http://ke.qq.com/webcourse/index.html#course_id=67888&term_id=100058920&taid=13934591901 ...
- shell(2):正则表达式
一.整理正则表达式博客 (1)正则 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. 在linux中,通配符是由shel ...
- Web开发者用什么编辑器?
写在前面的话:从事web前端开发也有一段时间了,今天主要想分享的是文字(代码)编辑器.对于编辑器每个人都有自己的偏爱,也分不同语言的编码者,这里我就拿我接触过的来说说吧! Web开发者用什么编辑器? ...
- 测试 MD
上面是一张图片 总店?
- 前端自动化工具 gulp
最近一个项目才接触这些自动化工具 webpack gulp grunt 等等.. webpack 可以引入模块 和 压缩 gulp 和 grunt 可以压缩 这里只说下gulp 因为项目里只用到gu ...
- ASP.NET MVC模式——WebPages
WebPages 示例 123456<html> <body> <h1>Hello Web Pages</h1> <p>The time i ...
- maven命令学习-发布上传jar包-deploy
Maven学习六之利用mvn deploy命令上传包 转http://blog.csdn.net/woshixuye/article/details/8133050 mvn:deploy在整合或者发布 ...
- linux新建文件和文件夹命令
1.touch命令 touch命令用来修改文件的访问时间.修改时间.如果没有指定时间,则将文件时间属性改为当前时间. 当指定文件不存在,touch命令变为创建该文件. 语法: touch [-acm] ...
- UML类图组成
本文转载至 http://blog.csdn.net/fengsh998/article/details/8105666 UML类图的相关知识,UML类图(Classdiagram)是最常用的 ...