ImageVerifierCode 换一换
格式:DOCX , 页数:110 ,大小:62.15KB ,
资源ID:7312316      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7312316.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(山东大学ACM模板数据结构.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

山东大学ACM模板数据结构.docx

1、山东大学ACM模板数据结构数据结构1. 二叉堆 32. 左偏树 33. 并查集_数组 94. 并查集_种类(未带路径压缩) 95. SpareTable_RMQ 106. 树状数组_壹23D 117. 树状数组_log二分 128. 树状数组_插段问段 139. 树状数组_rmq 1310. 线段树 1411. 线段树_二维求最值插点问段 1512. 线段树_寻找最左空间 1713. 后缀数组 1814. 归并树 1915. 归并树_K小元素_可修改值 2116. 划分树 2517. 划分树_返回k小元素下标 2718. 划分树-区间中位数 2919. 笛卡尔树 3120. 分数 3121.

2、Matrix_Double 3222. Gauss消元(精简版) 3423. Matrix_Integer 3424. 斐波那契 3725. Java小数高精度封装 3826. Java分数高精度封装 3927. BigInteger中需要注意的函数 4028. BigNumber 4029. 单调队列 4430. DLX 4531. DLX数独 4632. DLX多重覆盖 4933. hash_开放寻址 5334. HashMap_cpp 5435. Trie 5436. Treap 55二叉堆struct Nod int num; bool operator (const Nod&n) c

3、onst return num n.num; ;struct Heap Nod *arr壹00壹0; int len; void set(int idx, Nod *nod) /改变arr中值的唯一渠道。 arridx = nod; void init() len = 0; void push(Nod &nod) len +; set(len, &nod); up(len); Nod* pop() Nod* r = arr壹; set(壹, arrlen-); down(壹); return r; Nod* front() return arr壹; /下面是辅助方法,一般不用可以调用 void

4、 down(int p) int q = p壹; Nod *nod = arrp; while(q=len) if(qlen & *arrq+壹*arrq) q+; if(!(*arrq*nod) break; set(p, arrq); p = q; q = p壹; Nod *nod = arrp; while(q & *nod壹; set(p, nod); void build() for(int i = len/2; i 0; i -) down(i); ;左偏树/注释:initTree()只需调一次,NULL节点编号为0、D为-壹,单元素节点的L、R、D都为0int Kmaxn; /K

5、eyint Lmaxn, Rmaxn, Dmaxn; /左、右、disint Nmaxn; /本棵树节点个数int len; /资源使用量int rubbish; /【回收资源0】void initTree() /只需掉一次,清资源,设NULL节点 len = 壹; D0 = -壹; rubbish = 0; N0 = 0;struct LeftTree int r; /次树的根 LeftTree(int r = 0) /构造,传根,0表示为空树 this-r = r; void merge(LeftTree x) /this = this merge x r=merge(r, x.r); i

6、nt top() return Kr; int size() return Nr; int pop() /this = this pop min Dr = rubbish; rubbish = r;/【回收资源壹】 int t = Kr; r = merge(Lr, Rr); return t; void push(int key) /this = this push key int B; if(rubbish) /【回收资源2】 B = rubbish; rubbish = Drubbish; else B = len +; KB = key; LB = RB = DB = 0; NB =

7、壹; r = merge(r, B); void clear() /【待测】清空本树的资源,请保证这棵树是合法的; 如果是initTree后第一次建树,应该用=LeftTree() clear(r); r = 0; private: void clear(int idx) /【待测】 if(idx = 0) return; Didx = rubbish; rubbish = idx;/【回收资源3】 clear(Lidx); clear(Ridx); int merge(int A, int B) /合并A和B树,返回新树(此函数私有) if(A=0|B=0) return A+B; if(K

8、B KA) swap(A,B); /大于为最大堆 RA = merge(RA, B); if(DLA ry) py=x; return x; else px = y; if(rx = ry) ry +; return y; /华丽的分割线!以上是并查集/注释:initTree()只需调一次,NULL节点编号为0、D为-壹,单元素节点的L、R、D都为0int Kmaxn; /Keyint Lmaxn, Rmaxn, Dmaxn; /左、右、disint len; /资源使用量int rubbish; /【回收资源0】void initTree() /只需掉一次,清资源,设NULL节点 len =

9、 壹; D0 = -壹; rubbish = 0;struct LeftTree int r; /次树的根 LeftTree(int r = 0) /构造,传根,0表示为空树 this-r = r; void merge(LeftTree x) /this = this merge x r=merge(r, x.r); int top() return Kr; int pop() /this = this pop min Dr = rubbish; rubbish = r;/【回收资源壹】 int t = Kr; r = merge(Lr, Rr); return t; void push(i

10、nt key) /this = this push key int B; if(rubbish) /【回收资源2】 B = rubbish; rubbish = Drubbish; else B = len +; KB = key; LB = RB = DB = 0; r = merge(r, B); private: int merge(int A, int B) /合并A和B树,返回新树(此函数私有) if(A=0|B=0) return A+B; if(KB KA) swap(A,B); /大于为最大堆 RA = merge(RA, B); if(DLA DRA) swap(LA, RA

11、); DA = DRA+壹; /无论Ra是不是NULL,都满足 return A; ;LeftTree ltmaxn;void des(int a) int val = lta.pop(); lta.push(val / 2);int main() while(scanf(%d, &n) != EOF) make(); initTree(); for(int i = 0; i n; i +) scanf(%d, arr+i); lti = LeftTree(); lti.push(arri); int a, b, c; for(scanf(%d, &m); m -; ) scanf(%d%d,

12、 &a, &b); a = find(a-壹); b = find(b-壹); c = unio(a, b); if(c=-壹) printf(%dn, -壹); else des(a); des(b); lta.merge(ltb); ltc = lta; /将并查集的根的节点作为LeftTree的根 printf(%dn, ltc.top(); return 0;/* 【题目2】boi2004-Sequence 原题: 给定数列(Sequence)a壹.N (N壹06) 构造一个严格递增数列 b壹.N (bibj), 使得 |ai - bi| (i = 壹.N) 的和最小. 输出这个最小值

13、. solve : 对于Sequence b 先考虑 满足 bi=bj i = bi-壹 显然可以取 bi = ai, 若 ai bi-壹 则对于当前一个块(block, let rangecurrent block = k . i,每一个bj|j = k.i 的值均相同) keycurrent block 显然应该取 ak.i 的中位数,我们只需要不断维 护我们的 block 就可以了.而维护 block 的目的是选取中位数,我们就可以将 ak.i 中选 取最小的 ceil(i-k+壹)/2 个元素,询问最大值就可以了.而这显然可以使用 leftlist tree 这一种数据结构高效解决.

14、再考虑 b 先考虑 满足 bibj i r = r; void merge(LeftTree x) /this = this merge x r=merge(r, x.r); int top() return Kr; int size() return Nr; int pop() /this = this pop min Dr = rubbish; rubbish = r;/【回收资源壹】 int t = Kr; r = merge(Lr, Rr); return t; void push(int key) /this = this push key int B; if(rubbish) /【

15、回收资源2】 B = rubbish; rubbish = Drubbish; else B = len +; KB = key; LB = RB = DB = 0; NB = 壹; r = merge(r, B); private: int merge(int A, int B) /合并A和B树,返回新树(此函数私有) if(A=0|B=0) return A+B; if(KB KA) swap(A,B); /大于为最大堆 RA = merge(RA, B); if(DLA DRA) swap(LA, RA); DA = DRA+壹; /无论Ra是不是NULL,都满足 NA = NLA +

16、NRA + 壹; return A; ;/华丽的分隔线-以上是左偏树LeftTree ltmaxn;int qmaxn, m;long long getNotDec(int * a, int n, int * b) /【构造非降的序列b】 initTree(); m = 0; for(int i = 0; i =0 & ltm-2.top()ltm-壹.top() ltm-2.merge(ltm-壹); qm-壹 = qm; while(ltm-2.size() (qm-壹-qm-2)/2+壹) /取较大的那个中位数 ltm-2.pop(); m -; long long res = 0; f

17、or(int i = 0; i m; i +) for(int j = qi; j qi+壹; j +) bj = lti.top(); res += abs(aj-lti.top(); return res;long long getInc(int * a, int n, int * b) /【构造上升的序列b】 for(int i = 0; i n; i +) ai -= i; long long res = getNotDec(a, n, b); for(int i = 0; i n; i +) bi += i; return res;int arrmaxn, n, resmaxn;in

18、t main() while(scanf(%d, &n) != EOF) for(int i = 0; i n; i +) scanf(%d, arr+i); long long ans = getInc(arr, n, res); printf(%lldn, ans); for(int i = 0; i ry) py=x; return x; else px = y; if(rx = ry) ry +; return y; 并查集_种类(未带路径压缩)const int K = 3; /种类数,种类为0, k)int pmaxn, kmaxn; /父亲,种类号void make() mems

19、et(p, 255, sizeof(p); memset(k, 0, sizeof(k);int find(int x) if(px = -壹) return x; int px = px; px = find(px); kx = (kx + kpx) % K; return px;/*find的非递归版:int find(int x) int px, i, num = 0, tmp; for(px = x; ppx != -壹; px = ppx) num += kpx; while(x != px) tmp = kx; kx = num % K; num -= tmp; /和普通并查集的不

20、同 i = px; px = px; x = i; return px;*/d=a的种类-b的种类.返回true说明a、b未合并过bool unio(int a, int b, int d) int ra = find(a), rb = find(b); if(ra = rb) return false; prb = ra; krb = (ka-kb-d) % K + K) % K; return true;性质:在同一个并查集里面的编号都已经相对稳定经典用法:if(false = unio(a, b, d) if(ka - kb d) %K != 0) /因为此时已经find完了,所以直接掉kSpareTable_RMQ/* spare-table算法,取rmq壹.n中的极值 询问的时候,是闭区间*/ #define maxn 壹0000壹0int rmqmaxn;struct ST #d

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1