D. Broken BST
memory limit per test

256 megabytes

input

standard input

output

standard output

Let T be arbitrary binary tree — tree, every vertex of which has no more than two children. Given tree is rooted, so there exists only one vertex which doesn't have a parent — it's the root of a tree. Every vertex has an integer number written on it. Following algorithm is run on every value from the tree T:

  1. Set pointer to the root of a tree.
  2. Return success if the value in the current vertex is equal to the number you are looking for
  3. Go to the left child of the vertex if the value in the current vertex is greater than the number you are looking for
  4. Go to the right child of the vertex if the value in the current vertex is less than the number you are looking for
  5. Return fail if you try to go to the vertex that doesn't exist

Here is the pseudo-code of the described algorithm:

bool find(TreeNode t, int x) {
if (t == null)
return false;
if (t.value == x)
return true;
if (x < t.value)
return find(t.left, x);
else
return find(t.right, x);
}
find(root, x);

The described algorithm works correctly if the tree is binary search tree (i.e. for each node the values of left subtree are less than the value in the node, the values of right subtree are greater than the value in the node). But it can return invalid result if tree is not a binary search tree.

Since the given tree is not necessarily a binary search tree, not all numbers can be found this way. Your task is to calculate, how many times the search will fail being running on every value from the tree.

If the tree has multiple vertices with the same values on them then you should run algorithm on every one of them separately.

Input

First line contains integer number n (1 ≤ n ≤ 105) — number of vertices in the tree.

Each of the next n lines contains 3 numbers vlr (0 ≤ v ≤ 109) — value on current vertex, index of the left child of the vertex and index of the right child of the vertex, respectively. If some child doesn't exist then number  - 1 is set instead. Note that different vertices of the tree may contain the same values.

Output

Print number of times when search algorithm will fail.

Examples
input
3
15 -1 -1
10 1 3
5 -1 -1
output
2
input
8
6 2 3
3 4 5
12 6 7
1 -1 8
4 -1 -1
5 -1 -1
14 -1 -1
2 -1 -1
output
1
Note

In the example the root of the tree in vertex 2. Search of numbers 5 and 15 will return fail because on the first step algorithm will choose the subtree which doesn't contain numbers you are looking for.

题意:给出一颗二叉搜索树,不保证这棵树是正确的二叉搜索树,

那么按照二叉搜索树的搜索法则(小则往左,大则往右),就有可能找不到树上的某些节点

问找不到的节点有多少个

二叉搜索树,若根节点权值为10,那么左子树的权值范围为[-inf,9],右子树范围为[11,inf]

也就是说每个点的子节点可能的区间范围是确定的

若10有一个权值为a的左孩子,那么只有a的权值在[-inf,9]范围内,才能找到a

否则就找不到

右孩子同理

所以我们可以dfs统计满足要求的点的个数,

即若根节点权值为k,若左孩子权值在[l,k-1]之间,左孩子可以找到

若右孩子的权值在[k+1,r]之间,右孩子可以找到

最后 点的总数 减去 能找到的点的个数

注意:

1、累加可以找到的点时,累加这个权值的出现次数,

因为所有权值为这个的点,可能位于树的不同位置,但只要找到一个,所有权值为他的都可以找这一个

2、dfs(l[now],lk,min(v[now]-1,rk));    dfs(r[now],max(v[now]+1,lk),rk);

即注意dfs左子树时,区间右端点取大,dfs右子树时,区间左端点取小

为什么?因为点二叉搜索树是不正确的,到达位置错误的点时,要按错误的点来

为什么不直接累加不合法的?

累加合法的可以不用累加后清0,

累加不合法的可能是一个位置的不合法,但另一个位置的合法,

对于同一个权值,只要有一个位置合法,就能找到

#include<map>
#include<cstdio>
#include<algorithm>
#define N 100001
using namespace std;
int n,root,ans;
int v[N],l[N],r[N];
bool h[N];
map<int,int>sum;
int read()
{
int x=,f=;char c=getchar();
while(c<''||c>'') { if(c=='-') f=-;c=getchar(); }
while(c>=''&&c<='') { x=x*+c-''; c=getchar(); }
return x;
}
void dfs(int now,int lk,int rk)
{
if(v[now]>=lk&&v[now]<=rk) ans+=sum[v[now]];
if(l[now]>) dfs(l[now],lk,min(v[now]-,rk));
if(r[now]>) dfs(r[now],max(v[now]+,lk),rk);
}
int main()
{
n=read();
for(int i=;i<=n;i++)
{
scanf("%d%d%d",&v[i],&l[i],&r[i]);
sum[v[i]]++;
if(l[i]!=-) h[l[i]]=true;
if(r[i]!=-) h[r[i]]=true;
}
for(int i=;i<=n;i++)
if(!h[i])
{
root=i; break;
}
dfs(root,,1e9);
printf("%d",n-ans);
}

Codeforces 797 D. Broken BST的更多相关文章

  1. 【codeforces 797D】Broken BST

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

  2. Broken BST CodeForces - 797D

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

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

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

  4. codeforces 797 E. Array Queries【dp,暴力】

    题目链接:codeforces 797 E. Array Queries   题意:给你一个长度为n的数组a,和q个询问,每次询问为(p,k),相应的把p转换为p+a[p]+k,直到p > n为 ...

  5. CodeForces 797D Broken BST

    $dfs$,线段树. 通过观察可以发现,某位置要能被找到,和他到根这条路上的每个节点的权值存在密切的联系,且是父节点的左儿子还是右儿子也有联系. 可以从根开始$dfs$,边走边更新线段树,如果遍历左儿 ...

  6. Codeforces 797 F Mice and Holes

    http://codeforces.com/problemset/problem/797/F F. Mice and Holes time limit per test             1.5 ...

  7. Codeforces 1025 D - Recovering BST

    D - Recovering BST 思路:区间dp dp[l][r][0]表示l到r之间的数字可以构成一个二叉搜索树,并且以r+1为根节点 dp[l][r][0]表示l到r之间的数字可以构成一个二叉 ...

  8. 【26.34%】【codeforces 722A】Broken Clock

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  9. CodeForces - 24D :Broken robot (DP+三对角矩阵高斯消元 随机)

    pro:给定N*M的矩阵,以及初始玩家位置. 规定玩家每次会等概率的向左走,向右走,向下走,原地不动,问走到最后一行的期望.保留4位小数. sol:可以列出方程,高斯消元即可,发现是三角矩阵,O(N* ...

随机推荐

  1. 寒假MOOC学习计划

    我选择的是西北工业大学的课程,理由如下: 首先,选择这门课的网友还蛮多的,特意看了一下评价,也不错: 其次,这个课程的排版与我从图书馆借来的一本书内容排版比较符合,可以结合起来一起看,说不定会有更多收 ...

  2. 福大软工1816:Beta(3/7)

    Beta 冲刺 (3/7) 队名:第三视角 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务 文字/口头描述 参与开发关键词提醒部分 展示GitHu ...

  3. HDU 5651 xiaoxin juju needs help 逆元

    题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5651 bc:http://bestcoder.hdu.edu.cn/contests/con ...

  4. HDU 5418 Victor and World 允许多次经过的TSP

    题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5418 bestcoder(中文): http://bestcoder.hdu.edu.cn ...

  5. Java多线程中的wait与notify

    一.wait: 1. wait 是 object 类的方法, sleep 是 thread 类的方法. 2. 当前的正在我这个对象访问的线程 wait. 3. 当前的这个线程, 锁定在当前对象的这个线 ...

  6. 2nd 本周例行报告

    每周例行报告 1.个人项目:词频统计更新 C类型 C内容 S开始时间 E结束时间 I间隔(min) T净时间(min) 分析 功能分析 8:30 10:00 20 70 学习 查阅资料 10:00 1 ...

  7. 使用Kettle导出excel

    1.开发背景 在web项目中,经常会需要查询数据导出excel,以前比较常见的就是用poi.使用poi的时候也有两种方式,一种就是直接将集合一次性导出为excel,还有一种是分批次追加的方式适合数据量 ...

  8. bootstrap心得

    最近在弄个人的博客,之前对bootstrap的使用老是感觉使用的一般 幸好在看了慕课网的一个老师的实例教程之后,才感觉是真正对前端使用bootstrap有了一点理解 首先就是. 这些标签,其实都是相当 ...

  9. PHP中parent关键词

    parent关键词 parent表示“父母”的意思,在面向对象语法中,代表“父类” ——本质上就是代表父类这个“类”,而不是父类的“对象”: 其使用方式为: parent::属性或方法: //通常是静 ...

  10. HDU4675_GCD of Sequence

    很有意思的一个数论题. 是这样的,给你一个数数组a[i],其中给出的每一个数字和要求的数字方位都是[1,m],现在问你根据a[]构造一个b[],且a和b中间的不相等的元素的个数恰好有k个. 现在问你g ...