splay

省选模拟五 题解

强颜欢笑 提交于 2020-01-12 11:04:00
写在前面: 我好菜啊 伯努利数和自然数幂和的式子都能忘 A. 青蛙 标签: 贪心+二分 题解: 首先我们贪心的让尽量多的青蛙免费跳过去,可以二分求出 考虑剩下的青蛙如何让费用最小: 假如免费的青蛙非零,那么一定可以把中间的石头跳完 这种情况下其他每个青蛙的最小花费一定是一次 另一种情况是没有免费的青蛙 直接让花费最小的青蛙把中间的石头跳一遍,其他的花费仍然都为一次 B. 一起自习的日子 标签: 伯努利数 题解: 我们知道伯努利数有两种$B^{-}$和$B^{+}$ 其中: $$\sum\limits_{i=0}^{n}C_{n+1}^{i}B^{-}_{i}=0$$ $$B^{+}_{i}=(-1)^iB^{-}_{i}$$ $B^{-}$和$B^{+}$ 都可以来表示自然数幂和: $$\sum\limits_{i=0}^{n-1}i^m=\frac{1}{m+1}\sum\limits_{i=0}^{m}B^{-}_{i}C_{m+1}^{i}n^{m+1-i}$$ $$\sum\limits_{i=1}^{n}i^m=\frac{1}{m+1}\sum\limits_{i=0}^{m}B^{+}_{i}C_{m+1}^{i}n^{m+1-i}$$ C. 字符串 标签: 主席树+$LCT$+$SAM$ 题解: 设$ans[R][L]$代表也$R$为右端点的最长贡献 考虑在

POJ 3481 treap

一世执手 提交于 2020-01-12 04:42:26
Treap树   核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <cstdlib> #include <cmath> #include <utility> #include <vector> #include <queue> #include <map> #include <set> #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)>(y)?(y):(x)) #define INF 0x3f3f3f3f #define MAXN 100005 using namespace std; int cnt=1,rt=0; //节点编号从1开始 struct Tree { int key, size, pri, son[2]; //保证父亲的pri大于儿子的pri void set(int x, int y, int z) { key=x; pri=y; size=z; son[0]=son[1]=0; } }T[MAXN]; void rotate(int p, int &x) {

POJ 3481 treap

半城伤御伤魂 提交于 2020-01-11 12:54:34
Treap树   核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <cstdlib> #include <cmath> #include <utility> #include <vector> #include <queue> #include <map> #include <set> #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)>(y)?(y):(x)) #define INF 0x3f3f3f3f #define MAXN 100005 using namespace std; int cnt=1,rt=0; //节点编号从1开始 struct Tree { int key, size, pri, son[2]; //保证父亲的pri大于儿子的pri void set(int x, int y, int z) { key=x; pri=y; size=z; son[0]=son[1]=0; } }T[MAXN]; void rotate(int p, int &x) {

【洛谷P3369 普通平衡树】

爱⌒轻易说出口 提交于 2020-01-10 05:48:31
题目描述   您需要写一种数据结构,来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名) 查询排名为x的数 求x的前驱(前驱定义为小于x,且最大的数) 求x的后继(后继定义为大于x,且最小的数) 输入格式:   第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号 输出格式:   对于操作3,4,5,6每行输出一个数,表示对应答案 输入样例:   10   1 106465   4 1   1 317721   1 460929   1 644985   1 84185   1 89851   6 81968   1 492737   5 493598 输出样例:   106465   84185   492737 题解:   这题就在这里写下单点问题的splay问题总结吧。(一个一个问题来)   1.旋转 1 inline void update(int r) 2 { 3 if(r!=-1){ 4 sz[r]=num[r]; 5 if(ch[r][0]!=-1) sz[r]+=sz[ch[r][0]]; 6 if(ch[r][1]!=-1) sz[r]+=sz[ch[r][1]]; 7 } 8 } 9 inline void

【模板】文艺平衡树

无人久伴 提交于 2020-01-09 00:58:59
如题,是一个模板。。。 Splay: 1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <cctype> 6 7 inline void read(int & x) 8 { 9 x = 0; 10 int k = 1; 11 char c = getchar(); 12 while (!isdigit(c)) 13 if (c == '-') c = getchar(), k = -1; 14 else c = getchar(); 15 while (isdigit(c)) 16 x = (x << 1) + (x << 3) + (c ^ 48), 17 c = getchar(); 18 x *= k; 19 } 20 21 const int MAXN = 101015; 22 int n, m, x, y; 23 24 int a[101010]; 25 26 struct SplayHello 27 { 28 int rt = 0, tot = 0; 29 int cnt[MAXN]; 30 int siz[MAXN]; 31 int tag[MAXN]; 32 int val[MAXN]; 33 int faz[MAXN];

【模板】文艺平衡树

牧云@^-^@ 提交于 2020-01-09 00:58:08
题目大意:利用 splay 维护序列,支持区间反转操作。 题解:这里用 splay 维护的是下标的偏序关系,最后查询时也是按照下标从小到大进行查询。注:初始化引入两个极值点的作用是避免考虑 l-1,r+1 越界带来的不必要的麻烦。 代码如下 #include <bits/stdc++.h> using namespace std; const int maxn=1e5+10; const int inf=0x3f3f3f3f; int n,m,a[maxn]; struct node{ #define ls(x) t[x].ch[0] #define rs(x) t[x].ch[1] int ch[2],fa,val,size,rev; }t[maxn]; int tot,root; inline bool get(int o){return o==rs(t[o].fa);} inline void pushup(int o){t[o].size=t[ls(o)].size+t[rs(o)].size+1;} inline void pushdown(int o){ if(t[o].rev){ t[o].rev=0,t[ls(o)].rev^=1,t[rs(o)].rev^=1; swap(ls(ls(o)),rs(ls(o))),swap(ls(rs(o)),rs(rs(o)))

洛谷3391 文艺平衡树 平衡树模板95

非 Y 不嫁゛ 提交于 2020-01-09 00:57:15
上次被火星人prefix吊打,突然发现已经不会写splay了 于是来道模板题 区间反转? 打一些lazy标记,感觉和线段树没有差太多,而且交换左右儿子这操作真是妙 lazy标记 下传的时间要注意有些东西会变 1 #include <bits/stdc++.h> 2 #define N 500000 3 #define mid (l+r>>1) 4 using namespace std; 5 int n,m,x,y; 6 struct spla 7 { 8 int fa[N],c[N][2],size[N],tr[N]; 9 bool rev[N]; 10 int NODE,rt; 11 void up(int x) 12 { 13 size[x]=size[c[x][0]]+size[c[x][1]]+1; 14 } 15 void down(int x) 16 { 17 if(rev[x]) swap(c[x][0],c[x][1]),rev[x]=0,rev[c[x][0]]^=1,rev[c[x][1]]^=1; 18 } 19 void rot(int x) 20 { 21 int y=fa[x]; 22 down(y);down(x); 23 bool k=c[y][1]==x; 24 if(fa[y]) c[fa[y]][c[fa[y]][1]==y]=x; else

[线段树][Splay][树状数组]JZOJ 3292 发牌

我怕爱的太早我们不能终老 提交于 2020-01-08 16:17:00
Description 在一些扑克游戏里,如德州扑克,发牌是有讲究的。一般称呼专业的发牌手为荷官。荷官在发牌前,先要销牌(burn card)。所谓销牌,就是把当前在牌库顶的那一张牌移动到牌库底,它用来防止玩家猜牌而影响游戏。 假设一开始,荷官拿出了一副新牌,这副牌有N张不同的牌,编号依次为1到N。由于是新牌,所以牌是按照顺序排好的,从牌库顶开始,依次为1, 2,……直到N,N号牌在牌库底。为了发完所有的牌,荷官会进行N次发牌操作,在第i次发牌之前,他会连续进行Ri次销牌操作,Ri由输入给定。请问最后玩家拿到这副牌的顺序是什么样的? 举个例子,假设N = 4,则一开始的时候,牌库中牌的构成顺序为{1, 2, 3, 4}。 假设R1=2,则荷官应该连销两次牌,将1和2放入牌库底,再将3发给玩家。目前牌库中的牌顺序为{4, 1, 2}。 假设R2=0,荷官不需要销牌,直接将4发给玩家,目前牌库中的牌顺序为{1,2}。 假设R3=3,则荷官依次销去了1, 2, 1,再将2发给了玩家。目前牌库仅剩下一张牌1。 假设R4=2,荷官在重复销去两次1之后,还是将1发给了玩家,这是因为1是牌库中唯一的一张牌。 Input 第 1行,一个整数 N,表示牌的数量。 第 2行到第 N + 1行,在第 i + 1行,有一个整数Ri, 0≤Ri<N Output 第 1行到第N行:第 i行只有一个整数

平衡树学习笔记(3)-------Splay

最后都变了- 提交于 2019-12-30 05:45:14
Splay 上一篇: 平衡树学习笔记(2)-------Treap Splay是一个实用而且灵活性很强的平衡树 效率上也比较客观,但是一定要一次性写对 debug可能不是那么容易 Splay作为平衡树,它的平衡方式就是旋转 暴力旋转,赤裸裸的旋转,各种旋转 就是依靠玄学的旋转来保证自己的复杂度 不废话,上主题 \(\color{#9900ff}{定义}\) struct node { node *ch[2], *fa; //父亲,孩子 int val, siz; //权值,大小 node(node *fa = NULL, int val = 0, int siz = 0): fa(fa), val(val), siz(siz) { ch[0] = ch[1] = NULL; } //不写构造函数一时爽,一直不写一直爽~~~ bool isr() { return this == fa->ch[1]; } //当前点是否为父亲右孩子,旋转的时候用,方便 int rk() { return ch[0]? ch[0]->siz + 1 : 1; } //当前的排名 void upd() { siz = 1 + (ch[0]? ch[0]->siz : 0) + (ch[1]? ch[1]->siz : 0); } //维护信息 }pool[maxn], *tail, *root, *st

平衡树学习笔记

对着背影说爱祢 提交于 2019-12-30 05:44:55
平衡树学习笔记 洛谷是个好地方! // splay The Magical Splay BST 拓展与伸展树 (Splay) 一日通 杨思雨 2004国家集训队论文 《伸展树的基本操作与应用》 // treap 随机平衡二叉查找树Treap的分析与应用 // sbt Size Balanced Tree 翻译 《Size Balanced Tree》 SBT模板 // 非旋转treap https://www.luogu.org/blog/yhzq/solution-p3369 http://www.yhzq-blog.cc/fhq-treap%E6%80%BB%E7%BB%93/ // 可持久化Treap https://www.luogu.org/blog/user25438/solution-p3835 // 模板 https://github.com/Wowkiee/ACM-ICPC/tree/master/Template 二叉搜索树 删除 左右儿子都存在 用右子树的最小值代替自身 左右儿子不都存在 Splay 插入 插入后旋转到根 删除 将pre旋转到根, ne旋转到pre的右儿子。 第k大、排名、前驱后继 找到后旋转到根 其他技能 多次翻转/删除区间 Treap 插入 旋转以维持最小堆性质 删除 旋转使之成为可直接删除的点 前驱后继 在树上二分。 非旋转Treap