Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)
题意:
树的根节点为水源,编号为 1 。给定编号为 2, 3, 4, …, n 的点的父节点。已知只有叶子节点都是房子。
有 q 个操作,每个操作可以是下列两者之一:
+ v
,表示编号为 v 的房子被歹徒占领。- v
,表示歹徒退出编号为 v 的房子。
初始所有房子都没有歹徒。对于每次变化后,要求删除最少的边,使得所有有歹徒的房子均无法与水源连通;同时,在此基础上要求受影响的普通房子数量最少。
题解:
首先对树的根节点的子树分类,那么实际上最多删除的边就是子树个数。
对于每个子树,如果要求受影响的普通房子数量最少,那么其实就是求所有歹徒的房子的lca。
求这个lca,可以利用dfs序,选dfs序最小的那个结点和最大的那个结点求出的lca就是所有结点的lca(这个可以用set维护)
然后用树状数组维护有多少普通房子受到影响即可。
#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#define fi first
#define se second
using namespace std;
typedef pair<int, int> PII;
const int maxn = 1e5 + ;
int c[maxn*], F[maxn][];
int deep[maxn], p[maxn][], col[maxn];
vector<int> G[maxn];
set<PII> S[maxn][];
int n, x, tot, q;
char str[];
PII ans;
void Modify(int x, int s){
for(; x <= *n; x += x&(-x)) c[x] += s;
}
int Query(int y){
if(y <= ) return ;
int ans = ;
for(int x = y; x; x -= x&(-x)) ans += c[x];
return ans;
}
int query(int x, int y) { return Query(y) - Query(x-); } int lca(int u, int v)
{
if(deep[u] > deep[v]) swap(u, v);
for(int i = ; i >= ; i--) if(deep[p[v][i]] >= deep[u]) v = p[v][i];
if(u == v) return u;
for(int i = ; i >= ; i--) if(p[v][i] != p[u][i]) u = p[u][i], v = p[v][i];
return p[u][];
} void dfs(int x, int fa, int d, int lab){
p[x][] = fa;
deep[x] = d;
col[x] = lab;
F[x][] = ++tot;
for(auto to : G[x]){
if(to == fa) continue;
dfs(to, x, d+, lab);
}
F[x][] = ++tot;
if(G[x].size() == ) { Modify(F[x][], ); Modify(F[x][], ); }
} void lca_pre(){
for(int j = ; j <= ; j++)
for(int i = ; i <= n; i++)
p[i][j] = p[p[i][j-]][j-];
} int main()
{
freopen("gangsters.in", "r", stdin);
freopen("gangsters.out", "w", stdout);
cin>>n>>q;
for(int i = ; i < n; i++){
scanf("%d", &x);
G[x].push_back(i+);
}
int coln = G[].size();
for(int i = ; i < G[].size(); i++)
dfs(G[][i], , , i+);
lca_pre();
int u, v, uv;
while(q--){
cin>>str;
if(str[] == '+'){
scanf("%d", &x);
if(S[col[x]][].size() == ) ans.fi++;
if(S[col[x]][].size() > ){
u = (*S[col[x]][].begin()).se; v = (*--S[col[x]][].end()).se;
uv = lca(u, v);
if(G[uv].size() != ) ans.se -= query(F[uv][], F[uv][])/;
}
S[col[x]][].insert({F[x][], x});
S[col[x]][].insert({F[x][], x});
Modify(F[x][], -);
Modify(F[x][], -); u = (*S[col[x]][].begin()).se; v = (*--S[col[x]][].end()).se;
uv = lca(u, v);
if(G[uv].size() != ) ans.se += query(F[uv][], F[uv][])/; printf("%d %d\n", ans.fi, ans.se);
} else {
scanf("%d", &x);
if(S[col[x]][].size() == ) ans.fi--; u = (*S[col[x]][].begin()).se, v = (*--S[col[x]][].end()).se;
uv = lca(u, v);
if(G[uv].size() != ) ans.se -= query(F[uv][], F[uv][])/; S[col[x]][].erase({F[x][], x});
S[col[x]][].erase({F[x][], x});
Modify(F[x][], );
Modify(F[x][], ); if(S[col[x]][].size() > ){
u = (*S[col[x]][].begin()).se, v = (*--S[col[x]][].end()).se;
uv = lca(u, v);
if(G[uv].size() != ) ans.se += query(F[uv][], F[uv][])/;
} printf("%d %d\n", ans.fi, ans.se);
}
}
return ;
}
Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)的更多相关文章
- Gym 101142G : Gangsters in Central City(DFS序+LCA+set)
题意:现在有一棵树,1号节点是水源,叶子节点是村庄,现在有些怪兽会占领一些村庄(即只占领叶子节点),现在要割去一些边,使得怪兽到不了水源.给出怪兽占领和离开的情况,现在要割每次回答最小的割,使得怪兽不 ...
- Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组
C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...
- Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+ 树状数组或线段树
C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...
- Codeforces 570D TREE REQUESTS dfs序+树状数组 异或
http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory li ...
- Codeforces 570D TREE REQUESTS dfs序+树状数组
链接 题解链接:点击打开链接 题意: 给定n个点的树.m个询问 以下n-1个数给出每一个点的父节点,1是root 每一个点有一个字母 以下n个小写字母给出每一个点的字母. 以下m行给出询问: 询问形如 ...
- CodeForces 570D DFS序 树状数组 Tree Requests
参考九野巨巨的博客. 查询一个子树内的信息,可以通过DFS序转成线形的,从而用数据结构来维护. #include <iostream> #include <cstdio> #i ...
- Codeforces Round #381 (Div. 2) D. Alyona and a tree dfs序+树状数组
D. Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- Codeforces Round #381 (Div. 2) D dfs序+树状数组
D. Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...
随机推荐
- 成都Uber优步司机奖励政策(2月25日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- mysql源码
从代码的角度来说,没有丝毫设计感,尤其是优化器部分.不过那些是常年累积的原因,一些新加较独立的部分,设计的就很舒服,真正的面向对象做法.
- grep命令及正则
文本查找 grep,egrep,fgrep grep :Global Research 根据模式搜索文本,并将符合模式的文本行显示出来 模式:Pattern,文本字符和正则的元字符组合而成匹配条件 g ...
- Unity编辑器 - 鼠标悬停在控件上时改变鼠标样式
Unity编辑器 - 鼠标悬停在控件上时改变鼠标样式 摘自Unity文档 EditorGUIUtility.AddCursorRect public static void AddCursorRect ...
- [SHELL]shell中的数学运算
一,expr 太麻烦,看的脑壳疼 二,使用方括号 !!!! bash shell用这种方法只支持整数运算,z shell倒是支持浮点型运算 var_1= var_2= var_3= my_var_1 ...
- 孤荷凌寒自学python第七十九天开始写Python的第一个爬虫9并使用pydocx模块将结果写入word文档
孤荷凌寒自学python第七十九天开始写Python的第一个爬虫9 (完整学习过程屏幕记录视频地址在文末) 今天在上一天的基础上继续完成对我的第一个代码程序的书写. 到今天终于完成了对docx模块针对 ...
- Python3 Tkinter-Frame
1.创建 from tkinter import * root=Tk() for fm in ['red','blue','yellow','green','white','black']: Fram ...
- [C++] Class (part 1)
The fundamental ideas behind classes are data abstraction and encapsulation. Data abstraction is a p ...
- c++反射概念-简单介绍
C++ 反射机制的简单实现 C++并不支持反射机制,只能自己实现. 如果需要实现字字符串到函数到映射,一定要使用到函数指针. 简单实现反射机制,根据字符串来构造相应到类.主要有以下几点: (1) 可以 ...
- 【转】自定义(滑动条)input[type="range"]样式
1.如何使用滑动条? 用法很简单,如下所示: <input type="range" value="0"> 各浏览器原始样式如下: Chrome: ...