列队
https://www.luogu.org/problem/P3960 splay 我们观察每一行除了最后一个数之外的数在操作中是如何变化的。 如果出队在(x,y),那么第x行(除了最后一个数)会弹出第y个数,它后面的数依次左移,再在最后插入一个数(就是最后一列当前的第x个数);然后,对于最后一列,我们要弹出第x个数(插入到第x行),再在最后插入一个数(就是刚出队的那个)。 所以,我们无论是对于行还是列,都要执行两种操作:第一,弹出第k个数,第二,在尾部插入一个数。这可以用splay来实现。 但是这样的话空间复杂度是 O(nm) O ( n m ) 。 我们发现有些人从始至终都是左右相邻的,这些人对应的splay节点可以合并。 于是我们在维护splay的时候,所有连续的数的区间我们用一个节点维护,记录这个节点表示的区间的左右端点; 如果我们发现要弹出的数在某个节点内部,我们就把它拆开,拆成3个节点(其中中间那个节点只有一个数,就是我们要的那个数),拆点的过程可以直接跑splay上的insert,删除中间那个节点就是splay上的删除。 总时间复杂度为 O(nlogn) O ( n l o g n ) 。 #include <cstdio> namespace rqy{ //命名空间是为了防止和某些奇怪的变量命名冲突,也可以去掉 typedef long long LL; const