赛克oj 1528(二叉搜索树)
赛氪OJ-专注于算法竞赛的在线评测系统 (saikr.com)
题目描述
小明初始的二叉搜索树是空树,他有一个长度为2∗𝑛2∗n的排列𝑝p,按照顺序依次插入𝑝1,𝑝2,⋯ ,𝑝𝑛p1,p2,⋯,pn,形成一个大小为𝑛n的二叉搜索树𝑇T。
接下来有𝑛n个询问,第𝑖i个询问是询问插入𝑝𝑛+𝑖pn+i后该节点的深度。节点的深度是到根节点的最短路径长度。一条路径的长度定义为这条路径的节点个数。例如1−2−31−2−3这条路径包含33个节点,长度为33。
注意:每个询问不对接下来的询问造成影响,即插入𝑝𝑛+𝑖pn+i后回答该询问,会立刻删除该节点,再插入𝑝𝑛+𝑖+1pn+i+1。
背景知识如下。
-
二叉搜索树。二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。
-
二叉搜索树每次插入都是插入到叶子节点的位置。从根节点开始,插入的元素比当前位置元素小就往左走,比当前位置元素大就往右走,直到为空。
-
长度为𝑛n的排列指一个长度为𝑛n的序列,序列元素范围是[1,𝑛][1,n]的整数,且序列内的数两两不同。
输入
输入格式:
- 第一行输入一个整数𝑛n。
- 第二行输入长度为2∗𝑛2∗n的排列𝑝p。
输出
输出格式:
- 输出𝑛n行,每行一个数,第𝑖i行的数表示第𝑖i个询问的答案。
这题使用链表建树比较方便。
1 #define IO std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) 2 #define bug(x) cout<<#x<<" is "<<x<<endl 3 #include <bits/stdc++.h> 4 #define iter ::iterator 5 using namespace std; 6 typedef long long ll; 7 typedef pair<int,int>P; 8 #define pb push_back 9 #define mk make_pair 10 #define se second 11 #define fi first 12 #define rs o*2+1 13 #define ls o*2 14 15 16 typedef struct node{ 17 int x; 18 node *lson=nullptr; 19 node *rson=nullptr; 20 21 node(int y,node *l = nullptr ,node *r = nullptr) : x(y), lson(l), rson(r) {} 22 }*Tree; 23 24 25 26 27 int main(){ 28 IO; 29 int n; 30 cin>>n; 31 Tree root=nullptr; 32 for(int i=1;i<=n;i++){ 33 int x; 34 cin>>x; 35 if(i==1){ 36 root=new node(x,nullptr,nullptr); 37 continue; 38 } 39 Tree p=root,q=root; 40 int flag=0; 41 while(p){ 42 q=p; 43 if(x<p->x){ 44 p=p->lson; 45 flag=1; 46 } 47 else{ 48 p=p->rson; 49 flag=2; 50 } 51 } 52 53 Tree pp=new node(x,nullptr,nullptr); 54 55 if(flag==1)q->lson=pp; 56 else if(flag==2)q->rson=pp; 57 } 58 59 for(int i=1;i<=n;i++){ 60 int x; 61 cin>>x; 62 Tree p=root; 63 int cnt=1; 64 while(p){ 65 cnt++; 66 if(x<p->x){ 67 p=p->lson; 68 } 69 else{ 70 p=p->rson; 71 } 72 } 73 cout<<cnt<<endl; 74 } 75 76 77 78 }

浙公网安备 33010602011771号