2016 NEERC, Northern Subregional Contest G.Gangsters in Central City(LCA)
G.Gangsters in Central City
题意:一棵树,节点1为根,是水源。水顺着边流至叶子。该树的每个叶子上有房子。有q个询问,一种为房子u被强盗入侵,另一种为强盗撤离房子u。对于每个询问,要求给出最小的阀门数来阻断水流向强盗所在房子,且在阀门数最小的情况下求最小的误伤房子数(即没被入侵却被断水的房子)。
思路:观察可发现,与根相连的子树都是独立的,因此有每有一颗这样的子树里有强盗,则ans1++,每有一颗这样的子树强盗全部撤离则ans1--;因此要维护的是误伤数ans2,我们对每一个与根相连的子树独立处理。要想最小化ans2,那阀门一定要设置在强盗所在房子的LCA的上边,则当前误伤数为该LCA为根的子树叶节点数减去强盗数,再减去原来的误伤数,即可用差值更新ans2。对于求某一子树内所有强盗的LCA,需要知道一个结论:若干个节点的LCA为其中dfs序最大与最小的两节点的LCA。因此可以开若干个set维护每个子树内强盗节点的dfs序。
#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<set>
#define dd(x) cout<<#x<<" = "<<x<<" "
#define de(x) cout<<#x<<" = "<<x<<endl
#define pb push_back
#define all(x) x.begin(),x.end()
using namespace std;
const int maxn=1e5+10;
int head[maxn],cnt=0;
struct Edge
{
int v,ne;
} edge[maxn<<1];
void add(int u,int v)
{
edge[++cnt].ne=head[u];
edge[cnt].v=v;
head[u]=cnt;
}
int tot=0,fa[maxn][32],dep[maxn],sz[maxn],id[maxn],rk[maxn];//sz记录叶节点数
vector<int> tree;
void dfs(int f,int u,int deep)
{
id[u]=++tot;
rk[tot]=u;
dep[u]=deep;
sz[u]=edge[head[u]].ne==0;
fa[u][0]=f;
if (f==1)
tree.pb(id[u]);
for (int i=1; i<=22; ++i)
fa[u][i]=fa[fa[u][i-1]][i-1];
for (int i=head[u]; i; i=edge[i].ne)
{
int v=edge[i].v;
if (v==f)
continue;
dfs(u,v,deep+1);
sz[u]+=sz[v];
}
}
int lca(int u,int v)
{
if (dep[u]<dep[v])
swap(u,v);
for (int i=22,d=dep[u]-dep[v]; i>=0; --i)
if (d&(1<<i))
u=fa[u][i];
if (u==v)
return u;
for (int i=22; i>=0; --i)
if (fa[u][i]!=fa[v][i])
u=fa[u][i],v=fa[v][i];
return fa[u][0];
}
set<int> st[maxn];
int gan[maxn],man[maxn];//gan为强盗数,man为误伤数
int main()
{
freopen("gangsters.in","r",stdin);
freopen("gangsters.out","w",stdout);
int n,q;
scanf("%d%d",&n,&q);
for (int i=2; i<=n; ++i)
{
int v;
scanf("%d",&v);
add(i,v);
add(v,i);
}
dfs(1,1,1);
int ans1=0,ans2=0;
while (q--)
{
char op[2];
int u;
scanf("%s%d",op,&u);
int num=upper_bound(all(tree),id[u])-tree.begin();//通过u的dfs序判断u在哪个子树内
if (op[0]=='+')
{
st[num].insert(id[u]);
int mn=*st[num].begin(),mx=*(--st[num].end()),a=lca(rk[mx],rk[mn]);
if (!gan[num])
ans1++;
gan[num]++;
ans2+=sz[a]-gan[num]-man[num];
man[num]=sz[a]-gan[num];
}
else
{
st[num].erase(lower_bound(all(st[num]),id[u]));
gan[num]--;
if (!gan[num])
{
ans1--;
ans2-=man[num];
man[num]=0;
}
else
{
int mn=*st[num].begin(),mx=*(--st[num].end()),a=lca(rk[mx],rk[mn]);
ans2+=sz[a]-gan[num]-man[num];
man[num]=sz[a]-gan[num];
}
}
printf("%d %d\n",ans1,ans2);
}
return 0;
}
2016 NEERC, Northern Subregional Contest G.Gangsters in Central City(LCA)的更多相关文章
- 2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D:Distribution in Metagonia(构造)
http://codeforces.com/gym/100801/attachments 题意:给出一个数n(1 <= n <= 1e18),将 n 拆成 m 个整数,其中 m 必须是 2 ...
- 模拟赛小结:2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest
2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest 2019年10月11日 15:35-20:35(Solved 8,Penalty 675 ...
- 2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest (9/12)
$$2015-2016\ ACM-ICPC,\ NEERC,\ Northern\ Subregional\ Contest$$ \(A.Alex\ Origami\ Squares\) 签到 //# ...
- 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D】---暑假三校训练
2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D Problem D. Distribution in Metagonia Input ...
- 2016 NEERC, Moscow Subregional Contest K. Knights of the Old Republic(Kruskal思想)
2016 NEERC, Moscow Subregional Contest K. Knights of the Old Republic 题意:有一张图,第i个点被占领需要ai个兵,而每个兵传送至该 ...
- 2016-2017 ACM-ICPC, NEERC, Northern Subregional Contest
A. Anniversary Cake 随便挑两个点切掉就好了. #include<bits/stdc++.h> using namespace std; const int Maxn=2 ...
- ACM ICPC 2016–2017, NEERC, Northern Subregional Contest Problem J. Java2016
题目来源:http://codeforces.com/group/aUVPeyEnI2/contest/229510 时间限制:2s 空间限制:256MB 题目大意: 给定一个数字c 用 " ...
- 【题解】G.Graph(2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest)
题目链接G题 题意 序列 \(a_1,a_2,⋯,a_n\) 是一个排列, 当且仅当它含有 1 到 n 的所有整数. 排列 \(a_1,a_2,⋯,a_n\) 是一个有向图的拓扑排序,当且仅当对于每条 ...
- 2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest
A. Auxiliary Project 完全背包. #include<stdio.h> #include<iostream> #include<string.h> ...
随机推荐
- 第二讲,NT头文件格式,以及文件头格式
今天详解NT 头格式,以及文件头格式,以及作用, 关于DOS头文件格式,以及DOSStub昨天的博客已经写过了.主要是分散讲解.便于理解. 一丶最小PE的生成,以及标准PE的生成 ps: (如果直接学 ...
- hdu 6043 KazaQ's Socks
规律题.我自己写的规律对长度为2的要特判,wa一万次... 规律题目,容易错的反而是数据小的时候,得长记性. 题解:规律 先是1~n 然后1~n-2 n-1 1~n-2 n 交替出现 比如当n=4 ...
- arcgis之gp服务发布
arcgis之gp服务发布 注意: 1.arcgis服务可以直接通过arcmap来发布,gp服务就是将arcmap中的工具发布为服务,达到线上处理数据的能力 2.以文件为参数时不要以文件直接为参数,可 ...
- 网易云音乐ncm加密格式批量转换为flac,mp3
从网易云下载的某些付费歌曲下载下来会是ncm格式.ncm是个啥?就是你下完一首歌被网易云加密成它自己独有的ncm格式,这个ncm不能在其他播放器播放,如果网易云你会员到期了同样也会提示你无法播放(不是 ...
- parseInt parseFloat Number三者转换的方式
1.parseInt:从左到右检测字符串,若能先检测到数字,则将数字转换成整形,否则返回NaN. 2.parseFloat:从左到右检测字符串,若能先检测到数字,则将数字转换成浮点型,否则返回NaN. ...
- echo打印换行
shell环境中,echo是常用的数据命令,但有的时候,想通过“\n”使输出换行却换不了,这个时候需要增加-e选项: $ echo "Hellow.\nHey man~" Hell ...
- java 使用POI导出百万级数据
先看结果吧,这只是测试其中有很多因数影响了性能. 表总数为:7千多万,测试导出100万 表字段有17个字段 最终excel大小有60多兆 总耗时:126165毫秒 差不多2分多钟 其核心简单来说就是分 ...
- openresty 阶段说明
开发中常用的7阶段 set_by_lua*: 流程分支处理判断变量初始化 rewrite_by_lua*: 转发.重定向.缓存等功能(例如特定请求代理到外网) access_by_lua*: IP 准 ...
- 高级IO——文件锁
文件锁也被称为记录所,文件锁如果深讲的话,内容不少(比如文件锁最起码分为了建议锁和强制性锁,暂时挖坑,后面填). 文件锁作用 顾名思义,就是用来保护文件数据的.当多个进程共享读写同一个文件时,为了不让 ...
- 03_Redis_String命令
一:Redis命令---String命令:Redis 字符串数据类型的相关命令用于管理 redis 字符串值 字符串类型是Redis中最为基础.常用的数据存储类型,字符串在Redis中是二进制安全的, ...