[是男人就过8题——Pony.ai]Perfect N-P Arrays

题目大意:

一棵\(n(\sum n\le5\times10^6)\)个结点的树,每个结点都有一个括号。求树上一个合法的括号序列使得若将'('当成\(1\),')'当成\(-1\)。该序列最大前缀和最大,输出最大前缀和。

思路:

由于括号序列前缀和是连续的,所以我们可以把括号序列任意时刻前缀和\(\ge 0\)的限制给去掉。两遍树形DP求出从一个点出发最大/最小前缀和。绝对值取\(\min\)后即为经过这个点的最大答案。注意到最大/最小前缀和可能来自于同一棵子树,因此我们还需记录次大/次小值。

源代码:

  1. #include<cstdio>
  2. #include<cctype>
  3. #include<vector>
  4. #include<climits>
  5. #include<algorithm>
  6. inline int getint() {
  7. register char ch;
  8. register bool neg=false;
  9. while(!isdigit(ch=getchar())) neg|=ch=='-';
  10. register int x=ch^'0';
  11. while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
  12. return neg?-x:x;
  13. }
  14. const int N=1e6+1;
  15. std::vector<int> e[N];
  16. int w[N],ans,max[N][2],min[N][2];
  17. inline void add_edge(const int &u,const int &v) {
  18. e[u].push_back(v);
  19. e[v].push_back(u);
  20. }
  21. inline void upd1(const int &x,const int &y) {
  22. int tmp1=min[y][0]+w[x];
  23. int tmp2=max[y][0]+w[x];
  24. for(register int i=0;i<2;i++) {
  25. if(tmp1<min[x][i]) {
  26. std::swap(tmp1,min[x][i]);
  27. }
  28. if(tmp2>max[x][i]) {
  29. std::swap(tmp2,max[x][i]);
  30. }
  31. }
  32. }
  33. inline void upd2(const int &x,const int &y) {
  34. int tmp1=min[y][min[y][0]==min[x][0]+w[y]];
  35. int tmp2=max[y][max[y][0]==max[x][0]+w[y]];
  36. if(tmp1!=INT_MAX) tmp1+=w[x];
  37. if(tmp2!=INT_MIN) tmp2+=w[x];
  38. for(register int i=0;i<2;i++) {
  39. if(tmp1!=INT_MAX&&tmp1<min[x][i]) {
  40. std::swap(tmp1,min[x][i]);
  41. }
  42. if(tmp2!=INT_MIN&&tmp2>max[x][i]) {
  43. std::swap(tmp2,max[x][i]);
  44. }
  45. }
  46. }
  47. void dfs1(const int &x,const int &par) {
  48. max[x][0]=min[x][0]=w[x];
  49. max[x][1]=INT_MIN;
  50. min[x][1]=INT_MAX;
  51. for(auto &y:e[x]) {
  52. if(y==par) continue;
  53. dfs1(y,x);
  54. upd1(x,y);
  55. }
  56. }
  57. void dfs2(const int &x,const int &par) {
  58. for(auto &y:e[x]) {
  59. if(y==par) continue;
  60. ans=std::max(ans,std::min(std::abs(max[y][0]),std::abs(min[x][min[x][0]==min[y][0]+w[x]])));
  61. ans=std::max(ans,std::min(std::abs(min[y][0]),std::abs(max[x][max[x][0]==max[y][0]+w[x]])));
  62. upd2(y,x);
  63. dfs2(y,x);
  64. }
  65. }
  66. int main() {
  67. int n;
  68. while(~scanf("%d",&n)) {
  69. for(register int i=1;i<=n;i++) {
  70. const int p=getint();
  71. if(p) add_edge(p,i);
  72. w[i]=getint();
  73. }
  74. dfs1(1,0);
  75. dfs2(1,0);
  76. printf("%d\n",ans);
  77. for(register int i=1;i<=n;i++) {
  78. e[i].clear();
  79. }
  80. ans=0;
  81. }
  82. return 0;
  83. }

[是男人就过8题——Pony.ai]Perfect N-P Arrays的更多相关文章

  1. 【计蒜客】是男人就过 8 题--Pony.AI 题 A. A String Game 后缀自动机+SG函数

    [题目]A. A String Game [题意]给定目标串S和n个子串Ti,Alice和Bob轮流选择一个子串操作,必须且只能在子串末尾添加一个字符使得新串也是S的子串,不能操作即输,求胜利者.|S ...

  2. 是男人就过 8 题--Pony.AI A AStringGame

    链接:https://www.nowcoder.com/acm/contest/92/A来源:牛客网 AStringGame 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 26214 ...

  3. 是男人就过八题A_A String Game题解

    题意 给一个字符串\(s\),和\(n\)个子串\(t[i]\),两个人博弈,每次取出一个串\(t[i]\),在后面加入一个字符,保证新字符串仍然是\(s\)的子串,无法操作的人输. 分析 n个子串, ...

  4. leetcode第四题:Median of Two Sorted Arrays (java)

    Median of Two Sorted Arrays There are two sorted arrays A and B of size m and n respectively. Find t ...

  5. Kotlin实现LeetCode算法题之Median of Two Sorted Arrays

    题目Median of Two Sorted Arrays(难度Hard) 方案1,数组合并&排序调用Java方法 import java.util.* class Solution { fu ...

  6. FCC JS基础算法题(5):Return Largest Numbers in Arrays(找出多个数组中的最大数)

    题目描述: 找出多个数组中的最大数右边大数组中包含了4个小数组,分别找到每个小数组中的最大值,然后把它们串联起来,形成一个新数组.提示:你可以用for循环来迭代数组,并通过arr[i]的方式来访问数组 ...

  7. 【LeetCode每天一题】Median of Two Sorted Arrays(两数组中的中位数)

    There are two sorted arrays nums1 and nums2 of size m and n respectively.  Find the median of the tw ...

  8. 算法题之Median of Two Sorted Arrays

    这道题是LeetCode上的题目,难度级别为5,刚开始做没有找到好的思路,以为是自己智商比较低,后来发现确实也比较低... 题目: There are two sorted arrays nums1  ...

  9. 刷题4. Median of Two Sorted Arrays

    一.题目 Median of Two Sorted Arrays,具体请自行搜索. 这个题目,我看了一下,经过一番思考,我觉得实现起来不是很复杂. 但要做到bug free也不难,最大的问题是性能问题 ...

随机推荐

  1. JSON三种数据解析方法(转)

    原 JSON三种数据解析方法 2018年01月15日 13:05:01 zhoujiang2012 阅读数:7896    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blo ...

  2. docker 安装入门

    install docker 命令 docker version // docker 版本 docker pull nginx // 拉取nginx docker images // 查看本机dock ...

  3. [物理学与PDEs]第1章第6节 电磁场的标势与矢势 6.2 电磁场的标势与矢势

    1.  标势.矢势:  $$\beex \bea \Div{\bf B}=0&\ra \exists\ {\bf A},\st {\bf B}=\rot{\bf A},\\ \rot{\bf ...

  4. updateXML 注入 python 脚本

    用SLQMAP来跑updateXML注入发现拦截关键字,然后内联注入能绕,最后修改halfversionedmorekeywords.py脚本,结果SQLMAP还是跑不出来.>_< hal ...

  5. PHP循环语句深度理解分析——while, for, foreach, do while

    循环结构   一.while循环  while(表达式)  {   循环体;//反复执行,直到表达式为假  } 代码: $index = 1; while ($index<5) {        ...

  6. ES6走一波 数组的扩展

    Array flat 数组实例的扁平化方法(浏览器支持不佳) 建议使用 lodash的 flatten

  7. Log日志

    Log.e("tag", "错误信息");  Log.w("tag", "警告信息");  Log.i("ta ...

  8. Database学习 - mysql 视图/触发器/函数

  9. GNU MAKE参考文档

    1.GNU MAKE翻译 https://blog.csdn.net/xiejinfeng850414/article/details/8625468 2.Linux Makefile 生成 *.d ...

  10. 看完此文还不懂NB-IoT,你就过来掐死我吧...【转】

    转自:https://www.cnblogs.com/pangguoming/p/9755916.html 看完此文还不懂NB-IoT,你就过来掐死我吧....... 1 1G-2G-3G-4G-5G ...