最近开始重新学习Splay树写的第一题,基本就是照着别人博客改的一道题,关于Splay树的模板,感觉大牛已经把代码改得很短!!!这道题没什么难度,一个插入操作,一个找前驱,一个找后驱的操作。(话说这题有个数据有个bug的地方,可以看连接的discuss)。因为没有Push_Down,Push_Up的操作,感觉这题应该算是Splay树里面最水的一道了吧。
下面附上代码:(因为是第一题写Splay树,照着别人模板写的,然后写后面题的时候逐渐完善了一下)
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <iostream> #define ll long long #define MAXN 110000 using namespace std; struct SplayTree{ int root,size; int nt[MAXN][2],pre[MAXN],val[MAXN]; void init() {root = size = 0;} void newnode(int& rt,int father,int value){ rt = ++size; nt[rt][0] = nt[rt][1] = 0; pre[rt] = father; val[rt] = value; } void rotate(int x,int kind){ //0代表左旋,1代表右旋 int y = pre[x]; nt[y][!kind] = nt[x][kind]; pre[nt[x][kind]] = y; if(pre[y]){ nt[pre[y]][nt[pre[y]][1] == y] = x; } pre[x] = pre[y]; nt[x][kind] = y; pre[y] = x; } void Splay(int x,int goal){ while (pre[x] != goal) { if(pre[pre[x]] == goal){ rotate(x,nt[pre[x]][0] == x); } else{ int y = pre[x]; int kind = nt[pre[y]][0] == y; if(nt[y][kind] == x){ rotate(x,!kind); rotate(x,kind); } else{ rotate(y,kind); rotate(x,kind); } } } if (!goal) root = x; } bool insert(int k){ int rt = root; while(nt[rt][val[rt] < k]){ if(val[rt] == k){ Splay(rt,0); return false; } rt = nt[rt][val[rt] < k]; } newnode(nt[rt][val[rt] < k],rt,k); Splay(nt[rt][val[rt] < k],0); return true; } int get_pre(){ int x = nt[root][0]; while(x){ while(nt[x][1]){ x = nt[x][1]; } return val[x]; } return -1; } int get_next(){ int x = nt[root][1]; while(x){ while(nt[x][0]){ x = nt[x][0]; } return val[x]; } return -1; } }; SplayTree tree; int main(){ //freopen("test.in","r",stdin); int n; while(~scanf("%d",&n)){ int ans,x; scanf("%d",&ans); n --; tree.init(); tree.newnode(tree.root,0,ans); while(n --){ x = 0; scanf("%d",&x); if(tree.insert(x)){ int t1 = tree.get_pre(); int t2 = tree.get_next(); if(t1 == -1) ans += abs(t2 - x); else if(t2 == -1) ans += abs(x - t1); else { ans += min(x - t1,t2 - x); } } } printf("%d ",ans); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。