Splay!

  1 #include<cstdio>
  2 #include<cstdlib>
  3 const int mod =1000000007;
  4 const int inf  = ~0u>>2;
  5 const int maxn = 200010;
  6 int lim;
  7 struct SplayTree {
  8 19.    int sz[maxn];
  9 20.    int ch[maxn][2];
 10 21.    int pre[maxn];
 11 22.    int rt,top;
 12 23.    inline void up(int x){
 13 24.        sz[x]  = cnt[x]  + sz[ ch[x][0] ] + sz[ ch[x][1] ];
 14 25.    }
 15 26.    inline void Rotate(int x,int f){
 16 27.        int y=pre[x];
 17 28.        ch[y][!f] = ch[x][f];
 18 29.        pre[ ch[x][f] ] = y;
 19 30.        pre[x] = pre[y];
 20 31.        if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x;
 21 32.        ch[x][f] = y;
 22 33.        pre[y] = x;
 23 34.        up(y);
 24 35.    }
 25 36.    inline void Splay(int x,int goal){//将x旋转到goal的下面
 26 37.        while(pre[x] != goal){
 27 38.            if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x);
 28 39.            else   {
 29 40.                int y=pre[x],z=pre[y];
 30 41.                int f = (ch[z][0]==y);
 31 42.                if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);
 32 43.                else Rotate(y,f),Rotate(x,f);
 33 44.            }
 34 45.        }
 35 46.        up(x);
 36 47.        if(goal==0) rt=x;
 37 48.    }
 38 49.    inline void RTO(int k,int goal){//将第k位数旋转到goal的下面
 39 50.        int x=rt;
 40 51.        while(sz[ ch[x][0] ] != k-1) {
 41 52.            if(k < sz[ ch[x][0] ]+1) x=ch[x][0];
 42 53.            else {
 43 54.                k-=(sz[ ch[x][0] ]+1);
 44 55.                x = ch[x][1];
 45 56.            }
 46 57.        }
 47 58.        Splay(x,goal);
 48 59.    }
 49 60.    inline void vist(int x){
 50 61.        if(x){
 51 62.            printf("结点%2d : 左儿子  %2d   右儿子  %2d   %2d sz=%d\n",x,ch[x][0],ch[x][1],val[x],sz[x]);
 52 63.            vist(ch[x][0]);
 53 64.            vist(ch[x][1]);
 54 65.        }
 55 66.    }
 56 67.    inline void Newnode(int &x,int c){
 57 68.        x=++top;
 58 69.        ch[x][0] = ch[x][1] = pre[x] = 0;
 59 70.        sz[x]=1; cnt[x]=1;
 60 71.        val[x] = c;
 61 72.    }
 62 73.    inline void init(){
 63 74.        ans=0;type=-1;
 64 75.        ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;
 65 76.        rt=top=0; cnt[0]=0;
 66 77.        Newnode(rt,-inf);
 67 78.        Newnode(ch[rt][1],inf);
 68 79.        pre[top]=rt;
 69 80.        sz[rt]=2;
 70 81.    }
 71 82.    inline void Insert(int &x,int key,int f){
 72 83.        if(!x) {
 73 84.            Newnode(x,key);
 74 85.            pre[x]=f;
 75 86.            Splay(x,0);
 76 87.            return ;
 77 88.        }
 78 89.        if(key==val[x]){
 79 90.            cnt[x]++;
 80 91.            sz[x]++;
 81 92.            return ;
 82 93.        }else if(key<val[x]) {
 83 94.            Insert(ch[x][0],key,x);
 84 95.        } else {
 85 96.            Insert(ch[x][1],key,x);
 86 97.        }
 87 98.        up(x);
 88 99.    }
 89 100.    void Del(){
 90 101.         int t=rt;
 91 102.         if(ch[rt][1]) {
 92 103.             rt=ch[rt][1];
 93 104.             RTO(1,0);
 94 105.             ch[rt][0]=ch[t][0];
 95 106.             if(ch[rt][0]) pre[ch[rt][0]]=rt;
 96 107.         }
 97 108.         else rt=ch[rt][0];
 98 109.         pre[rt]=0;
 99 110.         up(rt);
100 111.    }
101 112.    void findpre(int x,int key,int &ans){
102 113.        if(!x)  return ;
103 114.        if(val[x] <= key){
104 115.            ans=x;
105 116.            findpre(ch[x][1],key,ans);
106 117.        } else
107 118.            findpre(ch[x][0],key,ans);
108 119.    }
109 120.    void findsucc(int x,int key,int &ans){
110 121.        if(!x) return ;
111 122.        if(val[x]>=key) {
112 123.            ans=x;
113 124.            findsucc(ch[x][0],key,ans);
114 125.        } else
115 126.            findsucc(ch[x][1],key,ans);
116 127.    }
117 128.    void solve() {
118 129.        int a,b,x,y;
119 130.        scanf("%d%d",&a,&b);
120 131.        if(a==type || sz[rt]==2){
121 132.
122 133.            Insert(rt,b,0),type=a;
123 134.            //printf("type=%d\n",type);
124 135.        }
125 136.        else {
126 137.            findpre(rt,b,x);
127 138.            findsucc(rt,b,y);
128 139.            if(abs(val[x]-b) <= abs(val[y]-b)) {
129 140.                ans+=abs(val[x]-b);
130 141.                ans%=mod;
131 142.                Splay(x,0);
132 143.                Del();
133 144.            }
134 145.            else {
135 146.                ans+=abs(val[y]-b);
136 147.                ans%=mod;
137 148.                Splay(y,0);
138 149.                Del();
139 150.            }
140 151.        }
141 152.        //spt.vist(rt);
142 153.    }
143 154.    int cnt[maxn];
144 155.    int val[maxn];
145 156.    int type;
146 157.    int ans;
147 158.}spt;
148 159.int main()
149 160.{
150 161.    int n;
151 162.    scanf("%d",&n);
152 163.    spt.init();
153 164.    while(n--)  spt.solve();
154 165.    printf("%d\n",spt.ans);
155 166.    return 0;
156 }  

Splay!

时间: 2024-08-11 21:50:22

Splay!的相关文章

【BZOJ】1500: [NOI2005]维修数列(splay+变态题)

http://www.lydsy.com/JudgeOnline/problem.php?id=1500 模板不打熟你确定考场上调试得出来? 首先有非常多的坑点...我遇到的第一个就是,如何pushup............sad.. 写了一大串...可是感觉...写不下去了...看别人怎么写吧... orz 首先这个节点代表的这个区间我们维护mxl和mxr表示整个区间从左向右和从右向左能得到的最大序列和.. 然后我无脑不思考没有用好我们的定义,写了一大串的转移... 其实就是几个字.. vo

【BZOJ-3786】星系探索 Splay + DFS序

3786: 星系探索 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 647  Solved: 212[Submit][Status][Discuss] Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球没有依赖星球. 我们定义依赖关系如下:若星球a的依赖星球是b,则有星球a依赖星球b.此外,依赖关系

Splay入门

目录 Splay入门 BST与Splay Rotate Splay 查找操作 插入 Update 前驱/后驱 前驱 后驱 删除 第k大 参考 Splay入门 BST与Splay 二叉查找树(BST),保证任意节点的左儿子小于其父亲,任意节点的右儿子大于其父亲的二叉树.但是当出现毒瘤数据时,BST会退化为链,从而影响效率.而Splay是其中的一种比较万能的填坑方法. Rotate Splay基本旋转操作.在不破坏二叉查找树(BST)结构的前提下,将一个节点向上旋转一层,使其曾经的父亲成为他现在的儿

3153: Sone1

这题网上题解比决战好像要多23333 先丢链接跪四位大爷 http://blog.csdn.net/iamzky/article/details/43494481 虽然理解之后大家都讲得很清晰 不过窝看了很久都木有看懂Orz 于是此篇题解尽量平易近人一些吧 窝突然想到一定会有人怀疑我做这种无脑数据结构题的意义…… 于是:我的人生,一片无悔~ ~~~~~吐槽时间~~~~~ 觉得杜教写法不太自然,然后写了个自然的,但是因为要维护子树信息……果断被教做人了 我猜我得调到十点了.一语成谶! 最后甚至都把

wikioi 1514 and ZJOI2006 书架

1514 书架 0人推荐 收藏 发题解 提交代码 报错 题目描述 输入描述 输出描述 样例输入 样例输出 提示 题目描述 Description 小 T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用 1 到 n 的正整数给每本书都编了号.     小 T 在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本.由于这些书太有吸引力了,所以她看完后常常会忘记原来是放在书柜的什么位置.不过小 T 的记忆力是非常好的,所以每次放书的时候至少能够将那本书放在拿出来时

splay:优雅的区间暴力!

万年不更的blog主更新啦!主要是最近实在忙,好不容易才从划水做题的时间中抽出一段时间来写这篇blog 首先声明:这篇blog写的肯定会很基础...因为身为一个蒟蒻深知在茫茫大海中找到一个自己完全能够看懂的blog有多么的难..(说多了都是泪.)所以当然希望所有初学者都能看懂这篇博文啦~ 说实话在学这个算法之前有跟强大的巨神zxyer学过treap和fhq_treap,所以对平衡树有一定的了解.当然都是理论阶段,虽然都打过一两题,但是忘得快..所以几乎等于没打. 认真重学了一遍平衡树(尤其是sp

【UOJ】【UR #2】猪猪侠再战括号序列(splay/贪心)

http://uoj.ac/problem/31 纪念伟大的没有调出来的splay... 竟然那个find那里写错了!!!!!!!!!!!!! 以后要记住:一定要好好想过! (正解的话我就不写了,太简单了.. #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #

BZOJ 1507 NOI2003 Editor Splay

题目大意: 1.将光标移动到某一位置 2.在光标后插入一段字符串 3.删除光标后的一段字符 4.输出光标后的一段字符 5.光标-- 6.光标++ 和1269很像的一道题,不过弱多了 几个问题需要注意: 1.插入的字符串中间居然会有回车!!没办法了,只能逐个字符进行读入,一旦读到'\n'或者'\r'就重新读入 2.题目描述中说Delete和Get操作后面一定会有足够的字符 纯属放P 连样例都没有足够的字符用来删除 所以删除时要和字符串长度取一个最小值 然后就水水地过去了~ 30%达成 今天是不是可

平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】

平衡树初阶——AVL平衡二叉查找树 一.什么是二叉树 1. 什么是树. 计算机科学里面的树本质是一个树状图.树首先是一个有向无环图,由根节点指向子结点.但是不严格的说,我们也研究无向树.所谓无向树就是将有向树的所有边看成无向边形成的树状图.树是一种递归的数据结构,所以我们研究树也是按照递归的方式去研究的. 2.什么是二叉树. 我们给出二叉树的递归定义如下: (1)空树是一个二叉树. (2)单个节点是一个二叉树. (3)如果一棵树中,以它的左右子节点为根形成的子树都是二叉树,那么这棵树本身也是二叉