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