fhq翻转

支持了pd和区间翻转

以及这里写的是按照子树大小分裂,是为了方便和序列对应上

顺便还有中序打印

#include <bits/stdc++.h>
#define F(i,i0,n) for(int i=i0;i<=n;i++)
#define mod 23333
#define ll long long
#define N 10000005
using namespace std;
inline int rd(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
struct Node{
    int l,r;
    int val,key,siz,tag;
}tr[N];
int cnt,rot;
inline void push_up(int p){tr[p].siz=tr[tr[p].l].siz+tr[tr[p].r].siz+1;}
inline void push_down(int p){
    if(!tr[p].tag)return ;
    swap(tr[p].l,tr[p].r);
    tr[tr[p].l].tag^=1;
    tr[tr[p].r].tag^=1;
    tr[p].tag=0;
}
void split(int u,int k,int &x,int &y){
    if(!u){
        x=y=0;
        return ;
    }
    push_down(u);
    if(tr[tr[u].l].siz<k){
        x=u;split(tr[u].r,k-tr[tr[u].l].siz-1,tr[u].r,y);
    }
    else {
        y=u;split(tr[u].l,k,x,tr[u].l);
    }
    push_up(u);
    
}
int merge(int x,int y){
    if(!x||!y)return x|y;
    if(tr[x].key>tr[y].key){
        push_down(x);
        tr[x].r=merge(tr[x].r,y);
        push_up(x);
        return x;
    }
    else {
        push_down(y);
        tr[y].l=merge(x,tr[y].l);
        push_up(y);
        return y;
    }
}
inline int newnode(int val){
    tr[++cnt].val=val;
    tr[cnt].key=rand();
    tr[cnt].siz=1;
    return cnt;
}
int x,y,z;
int n,m;
inline void work(int l,int r){
    split(rot,r,x,y);
    split(x,l-1,x,z);
    tr[z].tag^=1;
    rot=merge(merge(x,z),y);
}
void print(int u){
    push_down(u);
    if(tr[u].l)print(tr[u].l);
    cout<<tr[u].val<<" ";
    if(tr[u].r)print(tr[u].r);
}
signed main() {
    n=rd(),m=rd();
    F(i,1,n)rot=merge(rot,newnode(i));
    F(i,1,m){
        int l=rd(),r=rd();
        work(l,r);
    }
    print(rot);
    return 0;
}
posted @ 2023-09-09 17:09  ussumer  阅读(23)  评论(0)    收藏  举报