【破烂集】stl邪术——rope

之前做一道要用到splay的问题,因为并不会splay(同时懒得学习),所以就试图在论坛找找有没有偷懒的办法,没想到真的让我找到了,那就是rope这个结构,这个东西听说比较新,所以如果特别老的oj(比如poj和hdu)我觉得可能悬,不过dev(前提是新版的,不是机房那种)和牛客这些应该都可以支持。这个东西非常的方便,这里先留下一个坑(有兴趣的可以自己去查一查,相当于速成splay),之后研究了之后再慢慢补。

当我们说到数组时我们会说他的查询是o(1)的,当我们说到链表时,我们会说它的插入和区间转移是o(1)的,然而我们一直都有一个梦想,就是拥有一个能够兼具链表和数组优点的数据结构,虽然我们并不能找到严格o(1)的结构,但是logn的还是有的(比如splay),而rope理论上是一个块状数组,所以他的复杂度是n根号n,能够这个复杂度经过一些优化其实已经足够应付大部分问题了。下面举几个例子

先放一个代码
说的是这样一个问题,有一个排列,初始为1至n,进行q次操作,每次将l到r的排列转移到最前面(类似于切牌),问最后的排列

# include 
# include 

using namespace __gnu_cxx;

const int MAX_N = 1e5;

int main()
{
    rope<int> T;

    int N, M;
    scanf("%d %d", &N, &M);

    int i;
    for(i = 0; i < N ; i++)
        T.push_back(i + 1);

    while(M--)
    {
        int l, r;
        scanf("%d %d", &l, &r);
        l--;
        T = T.substr(l , r) + T.substr(0 , l) + T.substr(l + r , N - l - r);
    }

    for(i = 0 ; i < N ; i++)
        printf("%d ", T[i]);    

    return 0;
} 

rope区间reverse的问题也可以解决,当然你可能会说这不是splay板子题吗,但我们是要偷懒,所以这个时候维护两个rope即可,这两个rope互为revserse,这样要是转移哪个区间就交换他们当前部分的区间即可。

你可能感兴趣的:(破烂集)