如何用treap写luogu P3391

treap大法好!!!
splay什么的都是异端
——XZZ

先%FHQ为敬

(fhq)treap也是可以搞区间翻转的
每次把它成(1L-1)(LR)(R+1~n)三块然后打标记拼回去
对于有标记的先交换一下左右儿子再异或一下各儿子的标记
虽说跑的不算快但还是可以挑战一下splay的
代码蒯上

//get out splay!
#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gotcha()
{
    register int _a=0;bool _b=1;register char _c=getchar();
    while((_c<'0' || _c>'9') && _c!='-')_c=getchar();
    if(_c=='-')_b=0,_c=getchar();
    while(_c>='0' && _c<='9')_a=_a*10+_c-48,_c=getchar();
    return _b?_a:-_a;
}
const int _ = 100007;int seed=19260817;
inline int ou(){return seed=seed*17283%2147483647;}//看RP的时候到了
int ch[_][2],d[_],rn[_],sz[_],all=0,n,root=0;
int rev[_];
inline void up(int x){sz[x]=1+sz[ch[x][0]]+sz[ch[x][1]];}//更新节点值
inline void down(int x)//向下传递翻转标记
{
    if(x && rev[x])
    {
        rev[x]=0,swap(ch[x][0],ch[x][1]);
        if(ch[x][0])rev[ch[x][0]]^=1;
        if(ch[x][1])rev[ch[x][1]]^=1;
    }
}
inline int malloc(int v){sz[++all]=1;d[all]=v;rn[all]=ou();return all;}//新建一个节点
inline int merge(int a,int b)
{
    if(!a || !b) return a+b;down(a),down(b);
    if(rn[a]<rn[b]){ch[a][1]=merge(ch[a][1],b);up(a);return a;}
    else{ch[b][0]=merge(a,ch[b][0]);up(b);return b;}
}
void split(int now,int k,int &a,int &b)
{
    if(!now){a=b=0;return;}
    down(now);
    if(k<=sz[ch[now][0]])b=now,split(ch[now][0],k,a,ch[now][0]);
    else a=now,split(ch[now][1],k-sz[ch[now][0]]-1,ch[now][1],b); 
    up(now);
}
int plant(int l,int r)//种树
{
    if(l>r)return 0;
    int mid=(l+r)>>1,now=malloc(mid-1);
    ch[now][0]=plant(l,mid-1);ch[now][1]=plant(mid+1,r);
    up(now);return now;
}
void print(int now)//按中序遍历输出答案
{
    if(!now)return;down(now);
    print(ch[now][0]);
    if(d[now]>=1 && d[now]<=n)printf("%d ",d[now]);
    print(ch[now][1]);
    return;
}
void reverse(int l,int r)//旋转
{
    int a,b,c;
    split(root,l-1,a,b),split(b,r-l+1,b,c);
    rev[b]^=1;
    root=merge(a,merge(b,c));
}
int main()
{
    register int m,l,r;
    n=gotcha();m=gotcha();
    root=plant(2,n+3);
    while(m--)
    {
        l=gotcha(),r=gotcha();
        reverse(l,r);
    }
    print(root);
    return 0;
}

treap坠强!

posted @ 2017-09-27 13:00  iot;  阅读(518)  评论(3编辑  收藏  举报
知识共享许可协议
年轻人,你需要更多的知识