P3391 【模板】文艺平衡树(Splay)

来源:互联网 发布:app数据分析报告 编辑:程序博客网 时间:2024/05/18 02:51

题目背景

这是一道经典的Splay模板题——文艺平衡树。

题目描述

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

输入输出格式

输入格式:
第一行为n,m
n表示初始序列有n个数,这个序列依次是 (1,2,⋯n−1,n)
m表示翻转操作次数

接下来m行每行两个数 [l,r] 数据保证 1≤l≤r≤n
输出格式:
输出一行n个数字,表示原始序列经过m次变换后的结果

输入输出样例

输入样例#1:
5 3
1 3
1 3
1 4
输出样例#1:
4 3 2 1 5
说明
n,m≤100000

每次写数据结构都要调试一万年
加两个哨兵结点0,n+1,
每次伸展把root伸展到第r+2个,root->ch[0]伸展到第l个。

下面是代码

#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;const int N=100010,inf=10000010;int n,m;struct node{    node* ch[2];    int laz,s,v;    node(int v):v(v){s=1;ch[0]=ch[1]=NULL;laz=0;}    int cmp(int &k)    {        int ss=(ch[0] == NULL ? 0 : ch[0]->s);        if(k == ss+1) return -1;        if(k > ss) {k-=ss+1;return 1;}        return 0;    }    void maintain(){         s=1;         if(ch[0]!=NULL) s+=ch[0]->s;         if(ch[1]!=NULL) s+=ch[1]->s;     }    void pushdown()    {        if(laz)        {            swap(ch[0],ch[1]);            if(ch[0]!=NULL) ch[0]->laz^=1;            if(ch[1]!=NULL) ch[1]->laz^=1;            laz=0;        }    }};node* rt=NULL;void rot(node* &o,int d){    o->pushdown();node* k=o->ch[d^1];    k->pushdown();o->ch[d^1]=k->ch[d];k->ch[d]=o;    o->maintain();k->maintain();o=k;}void splay(node* &o,int k){    if(o == NULL) return ;    o->pushdown();    int d=o->cmp(k);    if(d != -1)    {        node* p=o->ch[d];if(p == NULL) return ;         p->pushdown();        int k2=k,d2=p->cmp(k2);        if(d2 != -1)         {             splay(p->ch[d2],k2);             if(d == d2) rot(o,d^1);             else rot(o->ch[d],d);         }        rot(o,d^1);    }}void ins(node* &o,int x){    if(o == NULL){o=new node(x);return ;}    int d=(x < o->v ? 0 : 1);ins(o->ch[d],x);    o->maintain();}void rev(int l,int r){    splay(rt,r+2);    splay(rt->ch[0],l);    if(rt->ch[0]->ch[1] != NULL)     rt->ch[0]->ch[1]->laz^=1;}int read(){    int out=0,f=1;char c=getchar();    while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}    while(c>='0'&&c<='9')     {out=(out<<1)+(out<<3)+c-'0';c=getchar();}    return out*f;}void print(node* o){    if(o==NULL) return ;    o->pushdown();    print(o->ch[0]);    if(o->v != n+1 && o->v)printf("%d ",o->v);    print(o->ch[1]);}void solve(){    n=read();m=read();    for(int i=1;i<=n+2;i++) {ins(rt,i-1);splay(rt,i);}    while(m--)    {        int l=read(),r=read();        rev(l,r);    }    print(rt);}int main(){    solve();    return 0;}
原创粉丝点击