$dfs$,线段树。

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

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

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std; int f[400010];
int s[400010];
int res; void pushDown(int rt)
{
if(f[rt]==0) return ;
s[2*rt] += f[rt];
s[2*rt+1] += f[rt];
f[2*rt] += f[rt];
f[2*rt+1] += f[rt];
f[rt] = 0;
return ;
} void pushUp(int rt)
{
s[rt] = s[2*rt] + s[2*rt+1];
} void update(int L,int R,int val,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
s[rt] += val;
f[rt] += val;
return ;
} int m = (l+r)/2;
pushDown(rt);
if(L<=m) update(L,R,val,l,m,2*rt);
if(R>m) update(L,R,val,m+1,r,2*rt+1);
pushUp(rt);
} void query(int pos,int l,int r,int rt)
{
if(l==r)
{
res = s[rt];
return;
} int m = (l+r)/2;
pushDown(rt);
if(pos<=m) query(pos,l,m,2*rt);
else query(pos,m+1,r,2*rt+1);
pushUp(rt); } int n;
struct X
{
int val;
int left,right;
}node[100010];
int root;
int b[100010],sz;
int ans; int get(int x)
{
int L = 0,R = sz-1; while(L<=R)
{
int mid = (L+R)/2;
if(b[mid]>x) R = mid-1;
else if(b[mid] == x) return mid+1;
else L = mid+1;
}
} int u[100010]; void dfs(int x,int y)
{
query(node[x].val,1,n,1);
if(res != y) {}
else u[node[x].val]=1; if(node[x].left!=-1)
{
if(node[x].val>1) update(1,node[x].val-1,1,1,n,1);
dfs(node[x].left,y+1);
if(node[x].val>1) update(1,node[x].val-1,-1,1,n,1);
} if(node[x].right!=-1)
{
if(node[x].val<n) update(node[x].val+1,n,1,1,n,1);
dfs(node[x].right,y+1);
if(node[x].val<n) update(node[x].val+1,n,-1,1,n,1);
} } int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&node[i].val,&node[i].left,&node[i].right); for(int i=1;i<=n;i++) b[sz++] = node[i].val;
sort(b,b+sz);
for(int i=1;i<=n;i++)
{
node[i].val = get(node[i].val);
u[node[i].val]=1;
} int sum=0;
for(int i=1;i<=n;i++) sum=sum+1; for(int i=1;i<=n;i++)
{
if(node[i].left!=-1) f[node[i].left] = 1;
if(node[i].right!=-1) f[node[i].right] = 1;
} for(int i=1;i<=n;i++)
{
if(f[i]) continue;
root = i; break;
} memset(f,0,sizeof f);
memset(u,0,sizeof u);
dfs(root,0);
for(int i=1;i<=n;i++) sum=sum-u[node[i].val]; printf("%d\n",sum); return 0;
}

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. cmd窗口关闭 -----window小技巧!

    前沿 平时开发的时候经常用到windows  的命令行工具来启动程序  或是 查看本地数据库的信息 : 经常的手动关闭 ,对于我这种,能用键盘完成的就坚决不用鼠标的人是多么痛苦. 所以在此罗列了一些命 ...

  2. 解决HTML5标签兼容的办法搜集

    HTML5的语义化标签以及属性,可以让开发者非常方便地实现清晰的web页面布局,加上CSS3的效果渲染,快速建立丰富灵活的web页面显得非常简单. HTML5的新标签元素有: <header&g ...

  3. 学大伟业 2017 国庆 Day1

    期望得分:100+100+20=220 实际得分:100+100+20=220 (好久没有期望==实际了 ,~\(≧▽≦)/~) 对于 a........a 如果 第1个a 后面出现的第1个b~z 是 ...

  4. HDU 4496 并查集 逆向思维

    给你n个点m条边,保证已经是个连通图,问每次按顺序去掉给定的一条边,当前的连通块数量. 与其正过来思考当前这边会不会是桥,不如倒过来在n个点即n个连通块下建图,检查其连通性,就能知道个数了 /** @ ...

  5. Linux系统调用和库函数

    #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unist ...

  6. Data science blogs

    Data science blogs A curated list of data science blogs Agile Data Science http://blog.sense.io/ (RS ...

  7. selenium.common.exceptions.ElementNotVisibleException: Message: element not visible处理方法:selenium针对下拉菜单事件的处理

    使用Selenium爬虫时,可能会遇到一些下拉菜单,动态加载,如果直接使用find_element_by_函数会报错,显示selenium.common.exceptions.ElementNotVi ...

  8. ⑥ 设计模式的艺术-06.建造者(Builder)模式

    场景 我们要建造一个复杂的产品.比如:神州飞船,Iphone.这个复杂的产品的创建.有这样一个问题需要处理: 装配这些子组件是不是有个步骤问题? 实际开发中,我们所需要的对象构建时,也非常复杂,有很多 ...

  9. Let's Encrypt 免费通配 https 签名证书 安装方法

    安装环境 centOs7 主要通过 acme.sh (bash脚本)来注册签名 git地址:https://github.com/Neilpang/acme.sh 申请证书流程 1.申请证书-> ...

  10. zedboard学习记录.1.纯PL流水灯

    环境:vivado 217.4 开发板: zedboard ver.d xc7z020clg484-1 1.打开Vivado新建一个RTL工程. 2.add source->add/create ...