题意:

树的根节点为水源,编号为 1 。给定编号为 2, 3, 4, …, n 的点的父节点。已知只有叶子节点都是房子。

有 q 个操作,每个操作可以是下列两者之一:

  1. + v ,表示编号为 v 的房子被歹徒占领。
  2. - 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 + 100;
int c[maxn*8], F[maxn][2];
int deep[maxn], p[maxn][30], col[maxn];
vector<int> G[maxn];
set<PII> S[maxn][2];
int n, x, tot, q;
char str[10];
PII ans;
void Modify(int x, int s){for(; x <= 2*n; x += x&(-x)) c[x] += s;
}
int Query(int y){if(y <= 0) return 0;int ans = 0;for(int x = y; x; x -= x&(-x)) ans += c[x];return ans;
}
int query(int x, int y) { return Query(y) - Query(x-1); }int lca(int u, int v)
{if(deep[u] > deep[v]) swap(u, v);for(int i = 20; i >= 0; i--) if(deep[p[v][i]] >= deep[u]) v = p[v][i];if(u == v) return u;for(int i = 20; i >= 0; i--) if(p[v][i] != p[u][i]) u = p[u][i], v = p[v][i];return p[u][0];
}void dfs(int x, int fa, int d, int lab){p[x][0] = fa;deep[x] = d;col[x] = lab;F[x][0] = ++tot;for(auto to : G[x]){if(to == fa) continue;dfs(to, x, d+1, lab);}F[x][1] = ++tot;if(G[x].size() == 0) { Modify(F[x][0], 1); Modify(F[x][1], 1); }
}void lca_pre(){for(int j = 1; j <= 20; j++)for(int i = 1; i <= n; i++)p[i][j] = p[p[i][j-1]][j-1];
}int main()
{freopen("gangsters.in", "r", stdin);freopen("gangsters.out", "w", stdout);cin>>n>>q;for(int i = 1; i < n; i++){scanf("%d", &x);G[x].push_back(i+1);}int coln = G[1].size();for(int i = 0; i < G[1].size(); i++)dfs(G[1][i], 1, 1, i+1);lca_pre();int u, v, uv;while(q--){cin>>str;if(str[0] == '+'){scanf("%d", &x);if(S[col[x]][0].size() == 0) ans.fi++;if(S[col[x]][0].size() > 0){u = (*S[col[x]][0].begin()).se; v = (*--S[col[x]][1].end()).se;uv = lca(u, v);if(G[uv].size() != 0) ans.se -= query(F[uv][0], F[uv][1])/2;}S[col[x]][0].insert({F[x][0], x});S[col[x]][1].insert({F[x][1], x});Modify(F[x][0], -1);Modify(F[x][1], -1);u = (*S[col[x]][0].begin()).se; v = (*--S[col[x]][1].end()).se;uv = lca(u, v);if(G[uv].size() != 0) ans.se += query(F[uv][0], F[uv][1])/2;printf("%d %d\n", ans.fi, ans.se);} else {scanf("%d", &x);if(S[col[x]][0].size() == 1) ans.fi--;u = (*S[col[x]][0].begin()).se, v = (*--S[col[x]][1].end()).se;uv = lca(u, v);if(G[uv].size() != 0) ans.se -= query(F[uv][0], F[uv][1])/2;S[col[x]][0].erase({F[x][0], x});S[col[x]][1].erase({F[x][1], x});Modify(F[x][0], 1);Modify(F[x][1], 1);if(S[col[x]][0].size() > 0){u = (*S[col[x]][0].begin()).se, v = (*--S[col[x]][1].end()).se;uv = lca(u, v);if(G[uv].size() != 0) ans.se += query(F[uv][0], F[uv][1])/2;}printf("%d %d\n", ans.fi, ans.se);}}return 0;
}

转载于:https://www.cnblogs.com/Saurus/p/7637377.html

Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)相关推荐

  1. Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum (离线树状数组+前缀xor)

    题目链接:http://codeforces.com/contest/703/problem/D 给你n个数,m次查询,每次查询问你l到r之间出现偶数次的数字xor和是多少. 我们可以先预处理前缀和X ...

  2. G. Gangsters in Central City

    给出一棵$1$为根节点的含$n$个节点的树,叶子节点都是房屋,在一个集合里面添加房屋和移除房屋. 每一次添加和移除后,回答下面两个问题. 1.  使得已选房屋都不能从根节点到达,最少需要砍多少条边. ...

  3. 2016-2017 ACM-ICPC, NEERC, Northern Subregional Contest G - Gangsters in Central City

    题目大意 现有一颗有根树,叶子节点可被染成黑色(最开始都是白色),也可以被染回白色,现在问给出每次染色信息后(即带修改),最少需要切断几条边保证黑色叶子不在树上,且在此条件下最少有多少白色叶子不在树上 ...

  4. Codeforces Round 261 Div.2 D Pashmak and Parmida's problem --树状数组

    题意:给出数组A,定义f(l,r,x)为A[]的下标l到r之间,等于x的元素数.i和j符合f(1,i,a[i])>f(j,n,a[j]),求有多少对这样的(i,j). 解法:分别从左到右,由右到 ...

  5. Educational Codeforces Round 80 (Rated for Div. 2) E. Messenger Simulator 思维 + 树状数组

    传送门 文章目录 题意: 思路: 题意: 给你nnn个人,一开始位置分别为1,2,...,n1,2,...,n1,2,...,n,让后mmm个操作,每次都将某个人移动到最前面,其他人依次顺延,求每个人 ...

  6. Gym 101142G Gangsters in Central City【思维+Lca】

    Gangsters in Central City 题意: 给一棵树,叶子节点为房子,q次操作,节点1为根节点(蓄水池)向房子供水 每次操作有两种类型,+ x 强盗占领了编号为x的房子,- x强盗离开 ...

  7. Codeforces Gym 100114 H. Milestones 离线树状数组

    H. Milestones Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descripti ...

  8. CodeForces 828E DNA Evolution(树状数组)题解

    题意:给你一个串k,进行两个操作: "1 a b":把a位置的字母换成b "2 l r s":求l到r有多少个字母和s匹配,匹配的条件是这样:从l开始无限循环s ...

  9. Gym - 101744E卡了我半天的题。。。。原来是才学的树状数组。。。

    最近学的不错的树状数组...比赛的时候居然忘记了,害的我卡了半天,心态炸掉了...再写一下题解 http://codeforces.com/gym/101744/problem/E 其实本题就是一个给 ...

最新文章

  1. 制定备份策略的指导方向思考
  2. OOD知识---对OOA\OOD\OOP思想
  3. 小心,疫情下在线教育免费试听引起的“后遗症”
  4. Struts入门(三)深入Struts用法讲解
  5. 手机MODEM 开发(29)--- VoLTE协议
  6. 嵌入式 Linux 设备的“瑞士军刀” BusyBox 受多个漏洞影响
  7. python36.dll下载_python36.dll
  8. 视频编解码(十二):播放器编解码流程source、demux、decoder、output
  9. 前端开源项目周报1213
  10. 安卓问题-第三方相关
  11. 绿化版IDEA启动时报IF you already have a 64-bit jdk错误的解决
  12. python查询IP归属地
  13. 通过Excel对各个商品的销售分析
  14. mysql 1114_ERROR 1114 (HY000): The table 'adv_date_tmp' is full(Mysql临时表应用)
  15. matlab中facedetector,Matlab人脸检测方法(Face Parts Detection)详解
  16. 项管行知05--可交付成果
  17. 餐饮行业最新的经营模式——私域运营案例
  18. 网站上做企业微信扫码授权登录怎么做?(超详细教程)
  19. UE4-(蓝图)动画中播放音效
  20. Latex之参考文献字体大小

热门文章

  1. ssh authentication魔鬼细节--.ssh文件夹权限
  2. 幻方 java_Java三阶幻方的8种结果输出
  3. 时间机器能成为现实么?
  4. mAP的计算公式是什么?
  5. DAY12 计蒜客 有趣的数字 爬楼梯 七巧板
  6. 总结一周:变量,数据类型,循环,函数
  7. linux smit工具,Aix操作系统SMIT工具
  8. aix服务器移动文件系统,AIX文件系统管理汇总:命令+SMIT实战
  9. Oracle常用问题1000问
  10. 《“通用语”与“兽人语”互译手册》之部落篇