• Gangsters in Central City

题意:

  • 给一棵树,叶子节点为房子,q次操作,节点1为根节点(蓄水池)向房子供水
  • 每次操作有两种类型,+ x 强盗占领了编号为x的房子,- x强盗离开了编号为x的房子。
  • 对每次操作,ans1计算出最少卡住几个节点使得强盗占领的房子都没水喝,ans2卡住这些点后没有被强盗占领的房子通不了水的数量最小,每次输出这两个数

思路:

  • 对根节点,如果有k个直接连接的点,拆成k棵子树。每棵有强盗占领的子树肯定最多只需要卡住一个点,那ans1就是k个子树中有强盗的的子树数量。
  • 对每棵子树求出被强盗占领的点dfs序最大的和最小的两个点的lca就是这棵子树中被强盗占领的所有的点的lca。处理出每个节点下有多少个房子(sz[i]),那么求出lca后,先减去没进行这次操作前这个子树的贡献,然后再加上这个操作,求出这颗子树上的点的lca,再加上这棵子树的贡献。ans2=sz[lca]-强盗占领的点

代码:

#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t) for(int i=(s);i<(t);++i)
#define per(i,s,t) for(int i=((t)-1);i>=(s);--i)
#define pb push_back
#define dd(x) cout<<#x<<'='<<x<<' '
#define de(x) cout<<#x<<'='<<x<<'\n'
#define fi first
#define se second
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
const int N=1e6+5;
int dp[N][20],n;
vi G[N];
set<int>st[N]; //维护第i棵子树中的dfs序
int tot,ver[N*2],R[N*2],First[N*2],bel[N],sz[N],cut[N];//cut[i] 第i棵子树中强盗占领的房子数量
//bel[i],节点i属于那棵子数
// First[u] u节点的在ver中第一次出现的下标,即dfs序
bool vis[N];
void dfs(int u,int dep){vis[u]=true;ver[++tot]=u;First[u]=tot;R[tot]=dep;rep(i,0,G[u].size()){int v=G[u][i];if(!vis[v]){dfs(v,dep+1);ver[++tot]=u;R[tot]=dep;}}
}
void ST(){rep(i,1,tot+1){dp[i][0]=i;}for(int j=1;(1<<j)<=tot;++j){for(int i=1;i+(1<<j)-1<=tot;++i){int a=dp[i][j-1];http://codeforces.com/group/aUVPeyEnI2/contest/229510/attachmentsint b=dp[i+(1<<(j-1))][j-1];if(R[a]<R[b])dp[i][j]=a;else dp[i][j]=b;}}
}
int RMQ(int l,int r){int k=0;while(1<<(k+1)<=r-l+1){k++;}int a=dp[l][k],b=dp[r-(1<<k)+1][k];return R[a]<R[b]?a:b;
}
int LCA(int u,int v){int res=RMQ(u,v);return ver[res];
}
void Dfs(int u,int rt){bel[u]=rt;vis[u]=true;if(G[u].size())sz[u]=0;else sz[u]=1;rep(i,0,G[u].size()){int v=G[u][i];if(!vis[v]){Dfs(v,rt);sz[u]+=sz[v];}}
}
int main()
{tot=0;memset(vis,0,sizeof(vis));memset(sz,0,sizeof(sz));int q,p;scanf("%d%d",&n,&q);rep(i,2,n+1){scanf("%d",&p);G[p].pb(i);}dfs(1,1);ST();memset(vis,0,sizeof(vis));rep(i,0,G[1].size()){Dfs(G[1][i],i+1);}int ans1=0,ans2=0;char op[10];int x,fa,mi,ma,lca;while(q--){scanf("%s%d",op,&x);if(op[0]=='+'){fa=bel[x];if(cut[fa]){mi=*st[fa].begin(),ma=*st[fa].rbegin();lca=LCA(mi,ma);ans2-=sz[lca]-cut[fa];}if(cut[fa]==0)ans1++;cut[fa]++;st[fa].insert(First[x]);mi=*st[fa].begin(),ma=*st[fa].rbegin();lca=LCA(mi,ma);ans2+=sz[lca]-cut[fa];}else{fa=bel[x];mi=*st[fa].begin(),ma=*st[fa].rbegin();lca=LCA(mi,ma);ans2-=sz[lca]-cut[fa];if(cut[fa]==1)ans1--;cut[fa]--;st[fa].erase(First[x]);if(cut[fa]){mi=*st[fa].begin(),ma=*st[fa].rbegin();lca=LCA(mi,ma);ans2+=sz[lca]-cut[fa];}}printf("%d %d\n",ans1,ans2);}return 0;
}

Gym 101142G Gangsters in Central City【思维+Lca】相关推荐

  1. codeforces gym 101142G Gangsters in Central City

    简略题意:一棵树,每个节点有一个局面,根是水源,边是水管.初始每个居民都有水喝. 操作有两种: '+ v', v处的居民楼被强盗占领. '- v', v处的强盗走了. 对于每个询问,你需要切断一些水管 ...

  2. Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)

    题意: 树的根节点为水源,编号为 1 .给定编号为 2, 3, 4, -, n 的点的父节点.已知只有叶子节点都是房子. 有 q 个操作,每个操作可以是下列两者之一: + v ,表示编号为 v 的房子 ...

  3. G. Gangsters in Central City

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

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

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

  5. Gym101142G Gangsters in Central City

    题目链接:https://cn.vjudge.net/problem/Gym-101142G 知识点: DFS序.LCA 题目大意: 给定一棵有根树(根为 \(1\)).每次修改叶子节点会被染成黑色( ...

  6. Codeforces Round #620 (Div. 2) E. 1-Trees and Queries 思维 + LCA

    传送门 文章目录 题意 思路: 题意 思路: 照例,先考虑不加边怎么做.由于可以经过重复的边或点,设aaa与bbb之间长度为lenlenlen,那么需要len<=klen<=klen< ...

  7. Gym - 102920 C - Dessert Café (思维)

    题意:一棵n个点的树上有k个特殊点,问满足以下条件的点a的个数: (1)到某个特殊点b的距离小于除a, b外的点到b的距离 (2)到某个特殊点c的距离小于b到c的距离 思路:求任意两个特殊点之间路径上 ...

  8. Codeforces - tag::data structures 大合集 [占坑 25 / 0x3f3f3f3f]

    371D 小盘子不断嵌套与大盘子,最后与地面相连,往里面灌水,溢出部分会往下面流,求每次操作时当前的盘子的容量 其实这道题是期末考前就做好了的.. 链式结构考虑并查集,然后没了(求大佬解释第一个T的点 ...

  9. Java黑皮书课后题第8章:*8.21(中心城市)给定一组城市,中心城市是和其它所有城市具有最短距离的城市。编写一个程序,提示用户输入城市数目以及位置(坐标),找到中心城市以及与其他城市总距离

    *8.21(中心城市)给定一组城市,中心城市是和其它所有城市具有最短距离的城市.编写一个程序,提示用户输入城市数目以及位置(坐标),找到中心城市以及与其他城市总距离 题目 题目描述与运行示例 破题 代 ...

最新文章

  1. 大话中文文本分类之DPCNN
  2. 种子谋定翻身-农民丰收节交易会·万建民:破解卡脖子难题
  3. net 控制台 定时_.NET Core实现基于Quart.Net的任务管理
  4. POJ 1091(数论)
  5. oracle的em能干什么,转载 解决Oracle的EM登录
  6. 2013年3月编程语言排行榜:有毒的Java
  7. 华为IoT平台NB编解码插件开发详细教程【下篇】
  8. Angularjs进阶笔记(2)—自定义指令中的数据绑定
  9. mysql definer super_技术分享 | 改写 mysqldump 解决 DEFINER 问题
  10. java 解决世界最难数独
  11. 写给初学者,一文搞懂大数据学习、岗位、面试及简历
  12. python建立源文件
  13. Android Studio实现多媒体播放器,音乐视频一体化
  14. 关于java面试被虐的痛苦经历,你有体验过吗?
  15. 9个超好用的学习网站,都是充实课余知识的首选
  16. 可编辑div的一些方法总结(二)自定义空格和回车事件
  17. 为什么linux虚拟机文件78g,linux 磁盘空间被占满但找不到目标文件的问题处理 lsof命令...
  18. TEACH_NLP——开篇
  19. ch340串口驱动_如何使用串口来给STM32下载程序
  20. ipref网络性能评估工具

热门文章

  1. 日本价值链促进会(IVI)秘书长西冈靖之:日本工业互联网发展情况
  2. 收藏能力升级,支付宝版「小程序桌面」初现!
  3. 英语时态和完成时详解
  4. C#求1000以内的完数
  5. 入会领京豆Python脚本
  6. 【自学】C语言程序设计
  7. 华强北的AirPods耳机谁家比较靠谱?
  8. 第九届蓝桥杯省赛JAVA语言 C组题解_题7 缩位求和
  9. Aid Learning更换壁纸
  10. 主导问题排查的流程总结