$dfs$,线段树。

通过观察可以发现,某位置要能被找到,和他到根这条路上的每个节点的权值存在密切的联系,且是父节点的左儿子还是右儿子也有联系。

可以从根开始$dfs$,边走边更新线段树,如果遍历左儿子,那么将$[1,val-1]$全部加$1$,否则将$[val+1,n]$全部加$1$,回溯的时候减$1$,判断某位置能否到达可以比较单点值与深度的关系。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cmath>
  4. #include <cstring>
  5. #include <string>
  6. #include <queue>
  7. #include <stack>
  8. #include <vector>
  9. #include <algorithm>
  10. using namespace std;
  11.  
  12. int f[400010];
  13. int s[400010];
  14. int res;
  15.  
  16. void pushDown(int rt)
  17. {
  18. if(f[rt]==0) return ;
  19. s[2*rt] += f[rt];
  20. s[2*rt+1] += f[rt];
  21. f[2*rt] += f[rt];
  22. f[2*rt+1] += f[rt];
  23. f[rt] = 0;
  24. return ;
  25. }
  26.  
  27. void pushUp(int rt)
  28. {
  29. s[rt] = s[2*rt] + s[2*rt+1];
  30. }
  31.  
  32. void update(int L,int R,int val,int l,int r,int rt)
  33. {
  34. if(L<=l&&r<=R)
  35. {
  36. s[rt] += val;
  37. f[rt] += val;
  38. return ;
  39. }
  40.  
  41. int m = (l+r)/2;
  42. pushDown(rt);
  43. if(L<=m) update(L,R,val,l,m,2*rt);
  44. if(R>m) update(L,R,val,m+1,r,2*rt+1);
  45. pushUp(rt);
  46. }
  47.  
  48. void query(int pos,int l,int r,int rt)
  49. {
  50. if(l==r)
  51. {
  52. res = s[rt];
  53. return;
  54. }
  55.  
  56. int m = (l+r)/2;
  57. pushDown(rt);
  58. if(pos<=m) query(pos,l,m,2*rt);
  59. else query(pos,m+1,r,2*rt+1);
  60. pushUp(rt);
  61.  
  62. }
  63.  
  64. int n;
  65. struct X
  66. {
  67. int val;
  68. int left,right;
  69. }node[100010];
  70. int root;
  71. int b[100010],sz;
  72. int ans;
  73.  
  74. int get(int x)
  75. {
  76. int L = 0,R = sz-1;
  77.  
  78. while(L<=R)
  79. {
  80. int mid = (L+R)/2;
  81. if(b[mid]>x) R = mid-1;
  82. else if(b[mid] == x) return mid+1;
  83. else L = mid+1;
  84. }
  85. }
  86.  
  87. int u[100010];
  88.  
  89. void dfs(int x,int y)
  90. {
  91. query(node[x].val,1,n,1);
  92. if(res != y) {}
  93. else u[node[x].val]=1;
  94.  
  95. if(node[x].left!=-1)
  96. {
  97. if(node[x].val>1) update(1,node[x].val-1,1,1,n,1);
  98. dfs(node[x].left,y+1);
  99. if(node[x].val>1) update(1,node[x].val-1,-1,1,n,1);
  100. }
  101.  
  102. if(node[x].right!=-1)
  103. {
  104. if(node[x].val<n) update(node[x].val+1,n,1,1,n,1);
  105. dfs(node[x].right,y+1);
  106. if(node[x].val<n) update(node[x].val+1,n,-1,1,n,1);
  107. }
  108.  
  109. }
  110.  
  111. int main()
  112. {
  113. scanf("%d",&n);
  114. for(int i=1;i<=n;i++)
  115. scanf("%d%d%d",&node[i].val,&node[i].left,&node[i].right);
  116.  
  117. for(int i=1;i<=n;i++) b[sz++] = node[i].val;
  118. sort(b,b+sz);
  119. for(int i=1;i<=n;i++)
  120. {
  121. node[i].val = get(node[i].val);
  122. u[node[i].val]=1;
  123. }
  124.  
  125. int sum=0;
  126. for(int i=1;i<=n;i++) sum=sum+1;
  127.  
  128. for(int i=1;i<=n;i++)
  129. {
  130. if(node[i].left!=-1) f[node[i].left] = 1;
  131. if(node[i].right!=-1) f[node[i].right] = 1;
  132. }
  133.  
  134. for(int i=1;i<=n;i++)
  135. {
  136. if(f[i]) continue;
  137. root = i; break;
  138. }
  139.  
  140. memset(f,0,sizeof f);
  141. memset(u,0,sizeof u);
  142. dfs(root,0);
  143. for(int i=1;i<=n;i++) sum=sum-u[node[i].val];
  144.  
  145. printf("%d\n",sum);
  146.  
  147. return 0;
  148. }

CodeForces 797D Broken BST的更多相关文章

  1. Broken BST CodeForces - 797D

    Broken BST CodeForces - 797D 题意:给定一棵任意的树,对树上所有结点的权值运行给定的算法(二叉查找树的查找算法)(treenode指根结点),问对于多少个权值这个算法会返回 ...

  2. AC日记——Broken BST codeforces 797d

    D - Broken BST 思路: 二叉搜索树: 它时间很优是因为每次都能把区间缩减为原来的一半: 所以,我们每次都缩减权值区间. 然后判断dis[now]是否在区间中: 代码: #include ...

  3. Codeforces 797 D. Broken BST

    D. Broken BST http://codeforces.com/problemset/problem/797/D time limit per test 1 second memory lim ...

  4. CodeForces 24D Broken robot(期望+高斯消元)

    CodeForces 24D Broken robot 大致题意:你有一个n行m列的矩形板,有一个机器人在开始在第i行第j列,它每一步会随机从可以选择的方案里任选一个(向下走一格,向左走一格,向右走一 ...

  5. CodeForces 1251A --- Broken Keyboard

    [CodeForces 1251A --- Broken Keyboard ] Description Recently Polycarp noticed that some of the butto ...

  6. 【codeforces 797D】Broken BST

    [题目链接]:http://codeforces.com/contest/797/problem/D [题意] 给你一个二叉树; 然后问你,对于二叉树中每个节点的权值; 如果尝试用BST的方法去找; ...

  7. CodeForces 24D Broken robot (概率DP)

    D. Broken robot time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  8. CodeForces 24D Broken Robot

    题意:n*m的棋盘,一个机器人在(i,j)处,每次等概率地停在原地,向左移动一格,向右移动一格,向下移动一格(不能移出棋盘).求走到最后一行所需期望步数.n<=1000,m<=1000 一 ...

  9. Codeforces.24D.Broken robot(期望DP 高斯消元)

    题目链接 可能这儿的会更易懂一些(表示不想再多写了). 令\(f[i][j]\)表示从\((i,j)\)到达最后一行的期望步数.那么有\(f[n][j]=0\). 若\(m=1\),答案是\(2(n- ...

随机推荐

  1. gcc和MinGW的异同

    cygwin/gcc和MinGW都是gcc在windows下的编译环境,但是它们有什么区别,在实际工作中如何选择这两种编译器. cygwin/gcc完全可以和在linux下的gcc化做等号,这个可以从 ...

  2. uva 11722 Joining with Friend

    https://vjudge.net/problem/UVA-11722 题意:你和朋友都要乘坐火车,并且都会途径A城市.你们很想会面,但是你们到达这个城市的准确时刻都无法确定.你会在时间区间[t1, ...

  3. KMP next表模板

    void makeNext(const char P[],int next[]) { int q,k;//q:模版字符串下标:k:最大前后缀长度 int m = strlen(P);//模版字符串长度 ...

  4. 《JavaScript 实战》:JavaScript 实现拖拽缩放效果

    拖拉缩放效果,实现通过鼠标拖动来调整层的面积(宽高)大小,例如选框效果.这里的拖拉缩放比一般的选框复杂一点,能设置八个方位(方向)的固定触发点,能设置最小范围,最大范围和比例缩放. 跟拖放效果一样,程 ...

  5. new Date('2014/04/30') 和 new Date('2014-04-30') 的区别

    new Date('2014/04/30') Wed Apr 30 2014 00:00:00 GMT+0800 (中国标准时间) new Date('2014-04-30'); Wed Apr 30 ...

  6. 【BZOJ】1707: [Usaco2007 Nov]tanning分配防晒霜

    [算法]贪心扫描线(+堆) [题意]给定n头牛有区间[a,b],m个防晒霜值为ai,每个可以使用bi次,每次可以使包含它的区间涂到防晒霜,问最多被涂牛数. [题解] 参考:[bzoj1707]: [U ...

  7. 24、简述Python的深浅拷贝以及应用场景

    深浅拷贝的原理 深浅拷贝用法来自copy模块. 导入模块:import copy 浅拷贝:copy.copy 深拷贝:copy.deepcopy 字面理解:浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝 ...

  8. 修改ecshop后台的管理菜单

    ecshop后台菜单如何去修改,下面ecshop开发中心如何去修改 首先先打开后台菜单项相关文件: admin\includes\inc_menu.php languages\zh_cn\admin\ ...

  9. es6新语法Object.assign()

    1.介绍 Object.assign用于对象的合并,将源对象的所有可枚举属性复制到目标对象,只拷贝源对象自身的属性继承属性补考呗 Object.assign(target,source1,...)第一 ...

  10. [MySQL] AUTO_INCREMENT lock Handing in InnoDB

    MySQL AUTO_INCREMENT lock Handing in InnoDB 在MySQL的表设计中很普遍的使用自增长字段作为表主键, 实际生产中我们也是这样约束业务开发同学的, 其中的优势 ...