[血压游戏] (https://ac.nowcoder.com/acm/contest/5278/G)

神奇的tag数组...,巧妙弥补了高度损失。

方法一:dsu on tree

类似长链剖分,不过是用unordered_map 来维护高度相关信息,swap复杂度是O(1)

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int inf = 0x3f3f3f3f;
  5. #define dbg(x...) do { cout << "\033[32;1m" << #x <<" -> "; err(x); } while (0)
  6. void err() { cout << "\033[39;0m" << endl; }
  7. template<class T, class... Ts> void err(const T& arg,const Ts&... args) { cout << arg << " "; err(args...); }
  8. const int N = 200000 + 5;
  9. int head[N], ver[N<<1], nxt[N<<1], tot;
  10. int dep[N];
  11. int n, rt;
  12. ll a[N], tag[N];
  13. unordered_map<int, ll> mp[N];
  14. void add(int x, int y){
  15. ver[++tot] = y, nxt[tot] = head[x], head[x] = tot;
  16. }
  17. void ins(int x, int d, ll cnt){
  18. if(!mp[x].count(d)){
  19. mp[x][d] = cnt + tag[x]; // x 下面的边数
  20. } else {
  21. mp[x][d] = max(mp[x][d] - tag[x], 1ll) + cnt + tag[x];
  22. }
  23. }
  24. void merge(int x, int y){
  25. if(mp[x].size() < mp[y].size()){
  26. swap(mp[x], mp[y]);
  27. swap(tag[x], tag[y]);
  28. }
  29. for(auto t : mp[y]){
  30. if(t.second){
  31. ins(x, t.first, max(t.second - tag[y], 1ll));
  32. }
  33. }
  34. }
  35. void dfs(int x, int fa){
  36. dep[x] = dep[fa] + 1;
  37. for(int i=head[x];i;i=nxt[i]){
  38. int y = ver[i];
  39. if(y == fa) continue;
  40. dfs(y, x);
  41. merge(x, y);
  42. }
  43. if(a[x])
  44. ins(x, dep[x], a[x]);
  45. tag[x] ++;
  46. }
  47. int main(){
  48. scanf("%d%d", &n, &rt);
  49. for(int i=1;i<=n;i++){
  50. scanf("%lld", &a[i]);
  51. }
  52. for(int i=1;i<n;i++){
  53. int x, y;scanf("%d%d", &x, &y);
  54. add(x, y);add(y, x);
  55. }
  56. dfs(rt, 0);
  57. ll res = 0;
  58. for(auto t : mp[rt]){
  59. if(t.second) res += max(1ll, t.second - tag[rt]);
  60. }
  61. cout << res << endl;
  62. return 0;
  63. }

方法二:

按照深度分组,建立虚树,然后树形DP求解即可

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int inf = 0x3f3f3f3f;
  5. #define dbg(x...) do { cout << "\033[32;1m" << #x <<" -> "; err(x); } while (0)
  6. void err() { cout << "\033[39;0m" << endl; }
  7. template<class T, class... Ts> void err(const T& arg,const Ts&... args) { cout << arg << " "; err(args...); }
  8. const int N = 200000 + 5;
  9. const int M = 2*N;
  10. int head[N], ver[M], nxt[M];
  11. int dfn[N], rnk[N], cnt;
  12. int dep[N], f[N][20];
  13. int st[N], top, inq[N];
  14. ll a[N];
  15. int n, rt, tot;
  16. vector<int> node[N];
  17. struct Graph{
  18. int head[N], ver[M], nxt[M], tot;
  19. void add(int x, int y){
  20. ver[++tot] = y, nxt[tot] = head[x], head[x] = tot;
  21. }
  22. }G;
  23. void add(int x, int y){
  24. ver[++tot] = y, nxt[tot] = head[x], head[x] = tot;
  25. }
  26. void dfs(int x, int fa){
  27. dfn[x] = ++cnt, rnk[cnt] = x;
  28. for(int i=head[x];i;i=nxt[i]){
  29. if(ver[i] == fa) continue;
  30. f[ver[i]][0] = x;
  31. dep[ver[i]] = dep[x] + 1;
  32. dfs(ver[i], x);
  33. }
  34. }
  35. int lca(int x, int y){
  36. if(dep[x] > dep[y]) swap(x, y);
  37. for(int i=19;i>=0;i--) if(dep[f[y][i]] >= dep[x]) y = f[y][i];
  38. if(x == y) return x;
  39. for(int i=19;i>=0;i--) if(f[y][i] != f[x][i]) y = f[y][i], x = f[x][i];
  40. return f[x][0];
  41. }
  42. void insert(int x){
  43. if(x == rt) return;
  44. int t = lca(x, st[top]);
  45. if(t != st[top]){
  46. while(top > 1 && dfn[st[top-1]] > dfn[t]){
  47. G.add(st[top-1], st[top]);
  48. top --;
  49. }
  50. if(dfn[t] > dfn[st[top-1]]){
  51. G.head[t] = 0;
  52. G.add(t, st[top]);
  53. st[top] = t;
  54. } else {
  55. G.add(t, st[top--]);
  56. }
  57. }
  58. G.head[x] = 0, st[++top] = x;
  59. }
  60. ll dfs(int x){
  61. if(inq[x]) return a[x];
  62. ll res = 0;
  63. for(int i=G.head[x];i;i=G.nxt[i]){
  64. int y = G.ver[i];
  65. ll val = dfs(y);
  66. if(val) // 没有就不要加
  67. res += max(val - dep[y] + dep[x], 1ll);
  68. }
  69. return res;
  70. }
  71. ll get(int x){
  72. if(!node[x].size()) return 0;
  73. sort(node[x].begin(), node[x].end(),[=](int a, int b){return dfn[a] < dfn[b];});
  74. st[top = 1] = rt; G.tot = 0; G.head[rt] = 0;
  75. for(auto t : node[x]) insert(t), inq[t] = 1;
  76. for(int i=1;i<top;i++){
  77. G.add(st[i], st[i+1]);
  78. }
  79. ll res = dfs(rt);
  80. if(res >= 2) res --;
  81. for(auto t : node[x]) inq[t] = 0;
  82. return res;
  83. }
  84. int main(){
  85. scanf("%d%d", &n, &rt);
  86. for(int i=1;i<=n;i++){
  87. scanf("%lld", &a[i]);
  88. }
  89. for(int i=1;i<n;i++){
  90. int x, y;scanf("%d%d", &x, &y);
  91. add(x, y);
  92. add(y, x);
  93. }
  94. dep[rt] = 1;
  95. dfs(rt, 0);
  96. for(int i=1;i<=n;i++){
  97. node[dep[i]].push_back(i);
  98. }
  99. for(int j=1;j<20;j++){
  100. for(int i=1;i<=n;i++){
  101. f[i][j] = f[f[i][j-1]][j-1];
  102. }
  103. }
  104. ll res = 0;
  105. for(int i=1;i<=n;i++){
  106. res += get(i);
  107. }
  108. cout << res <<endl;
  109. return 0;
  110. }

“科大讯飞杯”第18届上海大学程序设计联赛春季赛暨高校网络友谊赛 G 血压游戏的更多相关文章

  1. “盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛题解&&源码【A,水,B,水,C,水,D,快速幂,E,优先队列,F,暴力,G,贪心+排序,H,STL乱搞,I,尼姆博弈,J,差分dp,K,二分+排序,L,矩阵快速幂,M,线段树区间更新+Lazy思想,N,超级快速幂+扩展欧里几德,O,BFS】

    黑白图像直方图 发布时间: 2017年7月9日 18:30   最后更新: 2017年7月10日 21:08   时间限制: 1000ms   内存限制: 128M 描述 在一个矩形的灰度图像上,每个 ...

  2. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 C序列变换

    链接:https://www.nowcoder.com/acm/contest/91/C来源:牛客网没有账号的同学这样注册,支持博主 题目描述 给定两个长度为n的序列,ai, bi(1<=i&l ...

  3. K-序列(埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛)

    题目描述 给一个数组 a,长度为 n,若某个子序列中的和为 K 的倍数,那么这个序列被称为“K 序列”.现在要你 对数组 a 求出最长的子序列的长度,满足这个序列是 K 序列.  输入描述: 第一行为 ...

  4. SHU 第15届上海大学程序设计联赛夏季赛[热身赛] 第三题(G题) - 英语成绩

    看完题目就觉得是个图论题…… 每个人的成绩就是vertice,两个人的分数差就是edge,那么肯定类似于一种relax的方式,不断将每个人的成绩的min往上提, 当然,单纯的遍历一遍G.E肯定不可能就 ...

  5. “新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛(D题,贪心+栈)

    链接:https://ac.nowcoder.com/acm/contest/551/D来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语言10485 ...

  6. H、CSL 的拼图 【多维点的交换】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)

    题目传送门:https://ac.nowcoder.com/acm/contest/551/H 题目描述 众所周知 CSL 不仅玩魔方很强,打麻将也很强.今天他打魔法麻将的时候,在路上撞到了一个被打乱 ...

  7. G、CSL 的训练计划【BFS 贪心】(“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)

    题目传送门:https://ac.nowcoder.com/acm/contest/551/G 链接:https://ac.nowcoder.com/acm/contest/551/G来源:牛客网 题 ...

  8. F、CSL 的神奇序列 【规律】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)

    题目传送门:https://ac.nowcoder.com/acm/contest/551/F 题目描述 CSL 有一个神奇的无穷实数序列,他的每一项满足如下关系: 对于任意的正整数 n ,有 n∑k ...

  9. E、CSL 的魔法 【模拟】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)

    题目传送门:https://ac.nowcoder.com/acm/contest/551#question 题目描述 有两个长度为 n 的序列,a0,a1,…,an−1a0,a1,…,an−1和 b ...

随机推荐

  1. Windows下如何玩转火热的go-zero

    作者:阿啄debugIT 前言 go-zero 是一个集成了各种工程实践的 web 和 rpc 框架.通过弹性设计保障了大并发服务端的稳定性,经受了充分的实战检验. go-zero 包含极简的 API ...

  2. 【Flutter】可滚动组件之SingleChildScrollView

    前言 SingleChildScrollView类似于Android中的ScrollView,它只能接收一个子组件. 接口描述 const SingleChildScrollView({ Key ke ...

  3. 映泰主板H100系列安装win7的各种坑

    自100系列主板发布以来,windows7好像就被遗弃一样,原因就在于安装win7的时候,会出现USB设备无法使用导致无法安装的问题.主要在于Win7系统没有整合USB的XHCI驱动,而100系列芯片 ...

  4. MAVEN编译NIFI源码

    场景: 由于项目需求,需要借用NIFI进行二次开发,因此需要将NIFI源码进行修改,然后编译,办公环境无外网. 步骤: (1)   找一台可以上网(外网)的机器,安装java环境和maven环境,安装 ...

  5. 使用SimpleUpdater实现现有程序升级功能

    项目:https://github.com/iccfish/FSLib.App.SimpleUpdater C/S程式一般需要部署在多台机器上,如果程式有变动,需要一台一台重新安装,相当麻烦,如果我们 ...

  6. Java安全之Weblogic 2018-3248分析

    Java安全之Weblogic 2018-3248分析 0x00 前言 基于前面的分析,后面的还是主要看补丁的绕过方式,这里就来简单的记录一下. 0x01 补丁分析 先来看看补丁细节 private ...

  7. 18V转5V,18V转3.3V,18V转3V稳压芯片,0.01A-3A输出

    18V转5V,18V转3.3V,18V转3V, 18V转5V稳压芯片,18V转3.3V稳压芯片,18V转3V稳压芯片, 18V常降压转成5V电压,3.3V电压和3V电压给其他芯片或设备供电,适用于这个 ...

  8. 干电池1.5V升压3.3V芯片电路图

    1.5V升压3.3V的芯片 PW5100 是一款大效率.10uA低功耗.低纹波.高工作频率1.2MHZ的 PFM 同步升压 DC/DC 变换器.输入电压可低0.7V,输入电压范围0.7V-5V之间,输 ...

  9. 转 5 jmeter性能测试小小的实战

    5 jmeter性能测试小小的实战   项目描述 被测网址:www.sogou.com指标:相应时间以及错误率场景:线程数 20.Ramp-Up Period(in seconds) 10.循环次数 ...

  10. YOLOv4

    @ 目录 YOLO v4源码 CMake安装 CUDA安装 cuDNN安装 OpenCV安装 Cmake编译 VS编译 图像测试 测试结果 YOLOv4是最近开源的一个又快又准确的目标检测器. 首先看 ...