Codeforces 675D Tree Construction Splay伸展树
链接:https://codeforces.com/problemset/problem/675/D
题意:
给一个二叉搜索树,一开始为空,不断插入数字,每次插入之后,询问他的父亲节点的权值
题解:
由二叉搜索树的有序性质,
他的父亲节点一定是和他向上和向下最接近的两个中,最后插入的那一个
那么我们对于每一个数字标记其插入的时间,然后维护一棵平衡二叉树用于插值和查找用即可
主要是记录一下我的伸展树代码
据说指针比数组快,但是我这里不仅数组比指针快,甚至用vector和用数组的速度也是一样的
指针:
数组:
1.指针版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #include <bits/stdc++.h> #define endl '\n' #define ll long long #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) using namespace std; const int maxn=1e6+10,maxm=2e6+10; const int INF=0x3f3f3f3f; const int mod=1e9+7; const double PI= acos (-1.0); //head int casn,n,m,k; int num[maxn]; class splaytree{ public : struct splaynode{ splaynode *son[2],*pre; ll val; splaynode( int x=0,splaynode *fa=NULL){ pre=fa; son[0]=son[1]=NULL; val=x; } }; typedef struct splaynode* nodep; int cnt; nodep root; vector<splaynode> node; void rotate(nodep now, int d){ nodep fa=now->pre; fa->son[!d]=now->son[d]; if (now->son[d]) now->son[d]->pre=fa; now->pre=fa->pre; if (fa->pre){ if (fa->pre->son[0]==fa) fa->pre->son[0]=now; else fa->pre->son[1]=now; } else root=now; now->son[d]=fa; fa->pre=now; } void splay(nodep now,nodep dst){ while (now->pre!=dst){ if (now->pre->pre==dst)rotate(now,now->pre->son[0]==now); else { nodep fa=now->pre; int d=(fa->pre->son[0]==fa); if (fa->son[d]==now){ rotate(now,!d); rotate(now,d); } else { rotate(fa,d); rotate(now,d); } } } if (!dst) root=now; } int insert( int val){ if (!root) { node[cnt]=splaynode(val); root=&node[cnt++]; return 0; } nodep now=root; int flag=(now->val)<val; while (now->son[flag]){ if ((now->val)==val){ splay(now,NULL); return 0; } now=now->son[flag]; flag=((now->val)<val); } node[cnt]=splaynode(val,now); now->son[flag]=&node[cnt++]; splay(now->son[flag],NULL); return 1; } int bound( int d){ nodep now=root->son[d]; if (!now) return INF; while (now->son[d^1]) now=now->son[d^1]; return now->val; } splaytree( int n){ cnt=0; node.resize(n+7); root=NULL; } }; map< int , int > vis; int main() { IO; cin>>n; splaytree tree(n); while (n--){ int a; cin>>a; vis[a]=maxn-n; if (!tree.insert(a)) continue ; int mn=tree.bound(0); int mx=tree.bound(1); if (vis[mn]>vis[mx]) cout<<mn<< ' ' ; else cout<<mx<< ' ' ; } return 0; } |
2.数组版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | #include <bits/stdc++.h> #define endl '\n' #define ll long long #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) using namespace std; const int maxn=1e6+10,maxm=2e6+10; const int INF=0x3f3f3f3f; int casn,n,m,k; class splaytree{ #define nd node[now] public : struct splaynode{ int son[2],pre; ll val; splaynode( int x=0, int fa=0){ pre=fa; son[0]=son[1]=0; val=x; } }; int cnt; int root; vector<splaynode> node; void rotate( int now, int d){ int fa=nd.pre; node[fa].son[!d]=nd.son[d]; node[nd.son[d]].pre=fa; if (node[fa].pre){ node[node[fa].pre].son[node[node[fa].pre].son[1]==fa]=now; } else root=now; nd.pre=node[fa].pre; nd.son[d]=fa; node[fa].pre=now; } void splay( int now, int dst){ while (nd.pre!=dst){ if (node[nd.pre].pre==dst)rotate(now,node[nd.pre].son[0]==now); else { int fa=nd.pre; int d=(node[node[fa].pre].son[0]==fa); if (node[fa].son[d]==now){ rotate(now,!d); rotate(now,d); } else { rotate(fa,d); rotate(now,d); } } } if (!dst) root=now; } int insert( int val){ if (!root) { node[cnt]=splaynode(val); root=cnt++; return 0; } int now=root; int flag=nd.val<val; while (nd.son[flag]){ if (nd.val==val){ splay(now,0); return 0; } now=nd.son[flag]; flag=nd.val<val; } node[cnt]=splaynode(val,now); nd.son[flag]=cnt++; splay(nd.son[flag],0); return 1; } int bound( int d){ int now=node[root].son[d]; if (!now) return INF; while (nd.son[d^1]) now=nd.son[d^1]; return nd.val; } splaytree( int n){ cnt=1,root=0; node.resize(n+7); } }; map< int , int > vis; int main() { IO; cin>>n; splaytree tree(n); while (n--){ int a; cin>>a; vis[a]=maxn-n; if (!tree.insert(a)) continue ; int mn=tree.bound(0); int mx=tree.bound(1); if (vis[mn]>vis[mx]) cout<<mn<< ' ' ; else cout<<mx<< ' ' ; } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步