OI-数据结构
略
嘉伟森的猫
NYU Shanghai本科,MBZUAI机器学习硕士,深度学习/强化学习菜鸡
展开
-
poj 1208(链表)
传送门题意:(转自https://www.cnblogs.com/zhurb/p/5839701.html)给定一个长度n,有0~n-1编号的箱子和位置,起始个编号的箱子放在相同编号的位置。有一系列操作:move a onto b,将a,b上面的箱子放回初始位置,并将a放到b箱上。move a over b ,将a上面的箱子放回初始位置,并将a放到b箱最上方。pile a ...原创 2018-11-08 22:24:12 · 1804 阅读 · 0 评论 -
bzoj 4094(线段树)
传送门 题解:用线段树维护区间四个信息(左端点选/不选且右端点选/不选的区间最大不连续和),再记录四个信息中的最大值,然后每次修改都pushup到根并输出根的最大值即可。#include<bits/stdc++.h>using namespace std;#define root 1,1,n#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1原创 2017-10-03 19:34:15 · 251 阅读 · 0 评论 -
bzoj 2743(树状数组)
传送门 题解:对区间有贡献的数是从左端点往后所有第二次出现的数。一开始将每个数第二次出现的位置插入树状数组,然后将区间按x排序从左往右扫,每删除一个点i将nxt[i](i位置的数下一次出现的位置)从树状数组中删除,然后加入nxt[nxt[i]],对于每个区间用右端点在树状数组中query即可。#include<bits/stdc++.h>using namespace std;const in原创 2017-10-02 21:51:56 · 268 阅读 · 0 评论 -
bzoj 1935(树状数组)
传送门 题解:由于是静态问题所以可以离线处理,所有点(询问拆成4个)按x排序,二维可以转成一维,相当于每次query到的就是当前已插入的点,而只有这些点能对query的返回值造成贡献。 P.S.对于x坐标相同的插入/询问,要考虑这几个操作的先后顺序#include<bits/stdc++.h>using namespace std;const int MAXN=5e5+2;int n,nn原创 2017-10-02 20:56:12 · 256 阅读 · 0 评论 -
bzoj 3236(莫队+分块)
传送门 题解:将权值进行分块,然后序列上进行莫队操作。查询时整块的就for块,块两边的for点。修改O(1),查询(√n)。 这种100sec的题跑久了无异于卡评测,所以建议使用读入优化,可以快接近1/3的时间#include<bits/stdc++.h>using namespace std;#define pii pair<int ,int >#define mp(x,y) make_原创 2017-10-02 19:28:59 · 249 阅读 · 0 评论 -
bzoj 2120(带修改莫队)
传送门 题解:在普通莫队的基础上再维护一下时间,每次操作将当前时间之后的修改复原,将当前时间之前的修改完成后,再双指针移动即可。 听说块大小为n^(2/3)更快,有待考证#include<bits/stdc++.h>using namespace std;const int MAXN=1e4+2;int n,m;int a[MAXN],last[MAXN],cnt[1000002],an原创 2017-10-01 21:08:45 · 266 阅读 · 0 评论 -
bzoj 2212(线段树合并)
传送门 题解:权值线段树从下往上合并,每个点统计两个儿子中某一个交换/不交换的答案,取min后加到总答案中。不禁让人想起CDQZ Challenge 13 P.S.形态树开两倍空间,因为这种读入方式肯定会读成一棵满二叉树(不管存不存在子节点先加了时间戳)。另外,定义变量要搞清楚哪个是输入的形态树,哪个是线段树。#include<bits/stdc++.h>using namespace std原创 2017-10-01 10:40:45 · 349 阅读 · 0 评论 -
CDQZ Challenge 20
说在前面:“CDQZ”系列题目数据绝对良心(良苦用心233),提交网址如有需要请私信本蒟蒻。 1020:Challenge 20 查看 提交 统计 提问 总时间限制: 10000ms 单个测试点时间限制: 1500ms 内存限制: 512000kB 描述 给一个长为n的数列a_i(1≤i≤n),m次询问区间[L,R]中只出现了一次的数的最大值是多少.输入 第一行两个正整数n和m. 第二原创 2017-10-09 15:02:05 · 267 阅读 · 0 评论 -
9.30数据结构模拟赛
大意的后果:290分->40分 小小总结一下: 1.并查集按秩合并不要敲太快,不然不知不觉打上去个路径压缩就GG了。 2.把暴力程序的数组复制到正解程序的数组时一定要检查数组开没开够,毕竟暴力是针对30%的数据。。。 3.map等STL的具体用法要搞清楚。 题解:并查集按秩合并,然后查一下dep即可。#include<cstdio>#include<cstring>#include<i原创 2017-09-30 14:17:16 · 331 阅读 · 0 评论 -
CDQZ Challenge 16
说在前面:“CDQZ”系列题目数据绝对良心(良苦用心233),提交网址如有需要请私信本蒟蒻。 1016:Challenge 16 查看 提交 统计 提问 总时间限制: 80000ms 单个测试点时间限制: 10000ms 内存限制: 512000kB 描述 给你一个长度为n的数列a和m次询问。每次询问给定四个数l, r, x, y,表示询问在a[l .. r]中,对于所有x ≤ a[i]原创 2017-10-08 21:30:40 · 281 阅读 · 0 评论 -
bzoj 4530(DFS序+线段树合并)
传送门 题解:对每个点建权值线段树(权值即点在DFS序列中的编号),合并的时候直接合并两个点根的线段树,并连一下并查集,查询的时候找到x,y所在树的根f,假设dep[x]>dep[y],那答案就是(size[f]-size[x])*size[x](这一点的解释尽快补上,不过好像不比较也能过,难道是数据水?)。 P.S.在询问时要选深度更深的点的原因: 如果dep[x] < dep[y]并且选择原创 2017-09-29 21:57:46 · 270 阅读 · 0 评论 -
bzoj 3224(splay/treap)
传送门 慢的要死的splay,比别人的splay慢了至少30%。。。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=1e5+2;int ch[2][MAXN],f[MAXN],siz[MAXN],cnt[MAXN],key[M原创 2017-10-08 12:48:02 · 257 阅读 · 0 评论 -
bzoj 1901/zoj 2112(主席树+树状数组)
传送门 题解:又一道《万年A不掉》系列。外层树状数组维护内层权值线段树,修改/查询/空间复杂度都是(O(nlog(n)^2))。关于前缀,由静态root[r]-root[l]变为两个按树状数组lowbit处理过的root池(PL,PR)相减。 P.S.今天终于大概明白树状数组到底怎么在外层维护权值线段树,具体注释将尽快附上。#include<cstdio>#include<cstring>#原创 2017-10-07 23:08:54 · 372 阅读 · 0 评论 -
bzoj 2843(LCT)
传送门 题解:LCT维护区间和,支持单点修改。 注意:!!!不要写modify(read(),read()),好像是因为传参的顺序不确定,反正我就是因为这玩意儿TLE了半个多小时。。。#include<bits/stdc++.h>using namespace std;const int MAXN=3e4+5;int n,q;int fa[MAXN],ch[MAXN][2],rev[MA原创 2017-09-12 17:34:07 · 308 阅读 · 0 评论 -
spoj Query on a tree again(树链剖分)
传送门 题解:链剖,然后线段树维护1/0,每一次贪心地往左区间寻找(一条链对应到DFS序上越左深度越浅),最后返回一个下标。复杂度O(n*logn^2) 另外一种线段树写法戳这儿 P.S.用SPOJ评测一定不建议在main函数外写注释。 #include<cstdio>#include<cstring>#include<iostream>#include<algorithm>usin原创 2017-09-28 22:52:03 · 361 阅读 · 0 评论 -
spoj Query on a tree3/bzoj 1803(DFS序+主席树)
传送门 题解:在DFS序上维护主席树,每次修改权值线段树上一条链,链底时记录一下对应的树上点的编号,然后按主席树第k大的方式查询即可。 P.S.经常迷之CE,就是在bzoj上AC的代码都要CE。。。在本地DEV-C++把警告提示开到最大都没出错。。。 “prog.cpp:8:17: error: too many decimal points in numberApache/2.4.18 (U原创 2017-09-28 20:55:31 · 276 阅读 · 0 评论 -
Luogu 3865(st表)
传送门模板题,就怕某些毒瘤出题人卡线段树。#include#include#include#includeusing namespace std;const int N=1e5+4;int n,q;int mx[18][N],lg[N]={0,0};inline int read() { int x=0;char c=getchar(); while (c'9') c=原创 2017-11-07 19:28:36 · 265 阅读 · 0 评论 -
bzoj 1103(DFS序+树状数组)
传送门 题意: 两种操作: 1.修改某条边的边权(0/1) 2.询问某个点到1路径上的边权和题解: 在DFS序上差分+树状数组。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=250004;int n,m;int h原创 2017-10-13 11:48:11 · 294 阅读 · 0 评论 -
非旋转/可持久化treap(转自Sengxian's Blog)
非旋转 Treap 及可持久化 TreapPublished on 2017-10-12基本知识:普通堆,二叉搜索树,可持久化基本思想。介绍性质Treap = Tree + HeapTreap 是一颗同时拥有二叉搜索树和堆性质的一颗二叉树Treap 有两个关键字,在这里定义为:key\text{key}key:满足二叉搜索树性质,即中序遍历按转载 2017-10-13 12:04:02 · 460 阅读 · 0 评论 -
Luogu 1631(优先队列)
传送门题意:有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到个和,求这个和中最小的N个题解:先排序得到两个递增的数列a和b,然后用小根堆维护a+b,每次取队首,如果这次取出的是a[i]+b[j],则往队列中插入a[i]+b[j+1],所以需要另开一个数组p[i]来记录每一个a[i]应该匹配的b。正确性显然:取前k小值等价于取k次当前最小值,如果a[i]+b[j]都没被取到...原创 2018-08-15 19:56:00 · 206 阅读 · 0 评论 -
Luogu 1160(双向链表)
三个月不见,本蒟蒻阴魂不散死灰复燃,先来点水题找找感觉。题意:一个学校里老师要将班上N个同学排成一列,同学被编号为1~N,他采取如下的方法:1.先将1号同学安排进队列,这时队列中只有他一个人;2.2~N号同学依次入列,编号为i的同学入列方式为:老师指定编号为i的同学站在编号为1~i -1中某位同学(即之前已经入列的同学)的左边或右边;3.从队列中去掉原创 2018-02-01 22:01:39 · 307 阅读 · 0 评论 -
Luogu 3373(线段树标记混合下传)
传送门题意:nlogn实现区间加、区间乘、区间求和(都要求取模)题解:只要记住一句话:(x+a)*b=x*b+a*b,先乘后加,乘法标记管两个(sum,add),加法标记管一个(sum)。#include#include#include#includeusing namespace std;#define root 1,1,n#define lson rt<<1,l原创 2017-11-05 16:20:37 · 344 阅读 · 0 评论 -
Luogu 3378(堆)
传送门模板题。#include#include#include#includeusing namespace std;const int N=1e6+4; struct Heap { int a[N],siz=0; inline void push(int x) { a[++siz]=x; push_heap(a+1,a+siz+1,greater()); }原创 2017-11-05 16:55:41 · 263 阅读 · 0 评论 -
bzoj 4034(树链剖分)
传送门考前复习模板题(子树修改,单点修改,链上求和)。一晚上狂TLE,原因竟是:链剖siz比较写错,写了个轻链剖分。。。#includeusing namespace std;#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,r#define root 1,1,ntypedef long long ll;const i原创 2017-11-03 20:46:16 · 248 阅读 · 0 评论 -
bzoj 4756(线段树合并)
传送门 题解:显然可以用DFS序+主席树搞定,听说有一种处理子树的方法叫做线段树合并,所以专门写来试一试。建n棵动态开点的权值线段树,在形态树(输入的那个奶牛树)上从下往上合并线段树即可。#include<bits/stdc++.h>using namespace std;const int MAXN=1e5+4;int n,nn,a[MAXN],b[MAXN],ans[MAXN];int原创 2017-09-29 20:48:51 · 312 阅读 · 0 评论 -
Luogu 2827/bzoj 4721(单调队列)
传送门题解:如果x>y,显然x*p+q>(y+q)*p,所以:如果优先选最长的切,那么次长蚯蚓的子段一定也在最长蚯蚓的子段之后,所以用三个单调递减队列维护长度(原长,前半截,后半截),每次选三个队首最大的那个,切成两段扔进后两个队列,此时队列一定仍满足单调性。差不多就是个模拟题。。。P.S.上bzoj交的要注意处理行末空格以及回车,但在洛谷必须保留。。。Luogu 2827原创 2017-11-03 16:45:18 · 274 阅读 · 0 评论 -
bzoj 1878(莫队)(主席树)
传送门 解法: 1.莫队 2.可持久化线段树 3.(离线)树状数组 后两个应该略快一点,不过第一个实在是太好写了。。。#include<bits/stdc++.h>using namespace std;const int MAXN=5e4+4,MAXM=2e5+4;int n,m,siz;int cnt[1000004],bel[1000004],num[MAXN],ans[MA原创 2017-09-17 17:12:53 · 700 阅读 · 0 评论 -
bzoj 4448(LCA+主席树)(离线)
传送门 题解:先离线处理,以时间为下标维护区间内比i-c[i]小的数的个数,然后用LCA去查就好了。。。晚睡了一个小时,原因就是因为ans4初值没有赋成0,我以前还一向以为自己初始化变量很严谨,事实上严谨个*! 引以为戒!!!#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namesp原创 2017-09-17 01:57:08 · 267 阅读 · 0 评论 -
bzoj 2815(LCA+拓扑排序)(灭绝树)
传送门题意:在一个DAG中,问一个点是多少个点的支配点?题解:好像灭绝树就是因为这题被发明的。在DAG上拓扑排序时,通过在反图上倍增计算所有前驱的LCA,在新图(灭绝树)中add_edge(LCA,当前点)。最后对于每个点输出它在灭绝树上的子树大小-1(自己不算)。#include#include#include#include#include#include原创 2017-11-02 19:01:48 · 290 阅读 · 0 评论 -
bzoj 3223(非旋转treap/splay)
传送门~~~给不会写splay的Oier的福利~~~题解:维护一个合并式treap,打个类似于线段树lazy_tag的rev标记,每次需要翻转再进行左右儿子交换,记得pushdown就好。最后中序遍历一次treap即可得到所有操作后的序列。P.S.splay版的就不贴代码了,网上到处都有,下面是的合并式treap,与splay相比,速度略快(不靠读入优化),代码略短(^原创 2017-10-16 21:55:49 · 334 阅读 · 1 评论 -
codevs 2178(中缀表达式求值)
中缀表达式a + b*c + (d * e + f) * g,其转换成后缀表达式则为a b c * + d e * f + g * +。 转换过程需要用到栈,具体过程如下: 1)如果遇到操作数,我们就直接将其输出。 2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。 3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不原创 2017-11-10 21:58:55 · 526 阅读 · 0 评论 -
spoj D-Query(主席树)
传送门 题解: 听说是主席树一大基础应用就来试试看。在上一次出现的位置打-1,在这次出现的位置打+1,然后以在右端点的树上查询区间和即可。 P.S.为什么不加开点判重,开2*logn条链不会RE,加一个判重就WA了orz#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespac原创 2017-10-09 17:02:44 · 275 阅读 · 0 评论 -
bzoj 3224(非旋转treap)
传送门 附上两篇讲解: http://www.cnblogs.com/nietzsche-oier/p/6748292.html http://blog.csdn.net/zmh964685331/article/details/50536410 P.S.非旋转treap比普通treap慢,比splay快,可以实现splay能实现的而其余平衡树无法实现的操作比如区间翻转。#include<c原创 2017-10-15 17:42:36 · 269 阅读 · 0 评论 -
tyvj 1305(单调队列)
传送门 题意: 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大。题解: 维护一个关于前缀和的单调递增的队列,每次用队首更新答案,将元素插入队尾。 P.S.单调队列都做不来的弱鸡。。。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespac原创 2017-10-15 11:05:14 · 389 阅读 · 0 评论 -
bzoj 3262(cdq分治+树状数组)
(正经题解在后面)斜体字都是一年前在没有把cdq扯清楚的情况下应付的,即使现在真正理解了cdq,还是将这堆话留在这,毕竟,花无重开日,人无再少年——RunID User Problem Result Memory Time Language Code_Length Submit_Time 2374693 2711694897 32...原创 2017-10-23 19:53:30 · 342 阅读 · 0 评论 -
hdu 3530(单调队列)
传送门 题解: 用一个单调不升的队列维护最大值,一个单调不减的队列维护最小值。如果不满足条件,后移答案区间左端点,取两个队列头指针的元素较小的一个(位置尽量靠前使区间尽量长)。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=1原创 2017-10-13 21:53:47 · 503 阅读 · 0 评论 -
spoj Query on a tree(树链剖分)
传送门 题解:树链剖分边权问题,属于本人万年不想碰系列,以前做过不少剖点权的,今天来填填坑。其实两种问题唯一不同的就是:边权问题需要把边权下放到儿子作为点权,然后在链剖向上跳的最后一步稍作修改即可。关于记录一条边以及它对应权值下放的点,本蒟蒻想了一个办法就是用map < pair < int ,int> ,int >,其中pair记录一条边起点终点,最后一个int即这条边权值下放的点编号。经过肉眼原创 2017-09-28 19:53:16 · 222 阅读 · 0 评论 -
bzoj 3524(主席树+二分)
传送门 题解:建主席树,然后由于这个题的性质:区间[l,r]内出现次数大于(r-l+1)/2的数一定只有一个,要么在[l,mid]中,要么在[mid+1,r]中,所以可以通过在主席树上二分查找得到。 如果换成大于(r-l+1)/3可能就要想别的办法了。。。#include<bits/stdc++.h>using namespace std;#define lson lc[pre],lc[rt原创 2017-09-12 15:27:05 · 320 阅读 · 0 评论 -
CDQZ Challenge 13
说在前面:“CDQZ”系列题目数据绝对良心(良苦用心233),提交网址如有需要请私信本蒟蒻。 1013:Challenge 13 查看 提交 统计 提问 总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 262144kB 描述 给一个长为N的数列,有M次操作,操作仅有一种(每个位置刚开始都分别属于单独的一个集合):合并两个位置所属的集合,并求出两集合间形成的逆序原创 2017-08-13 16:49:24 · 384 阅读 · 0 评论 -
hdu 4366(线段树+DFS序)
传送门 问题:给出一棵树,除根结点(0)以外每个点有一个能力值和忠诚度,查询u所在子树结点中找一个能力值比u高并且忠诚度尽量大的点,输出其编号。按能力值从高到低排序,建出线段树维护区间最大值,跑出dfs序后,先查询,再插入。#pragma comment(linker,"/STACK:1024000000,1024000000")#include<cstdio>#include<cstring原创 2017-08-05 22:31:55 · 298 阅读 · 0 评论