[BZOJ]3223 文藝平衡樹 區間翻轉
阿新 • • 發佈:2019-02-05
3223: Tyvj 1729 文藝平衡樹
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 4861 Solved: 2851
[Submit][Status][Discuss]
Description
您需要寫一種資料結構(可參考題目標題),來維護一個有序數列,其中需要提供以下操作:翻轉一個區間,例如原有序序列是5 4 3 2 1,翻轉區間是[2,4]的話,結果是5 2 3 4 1
Input
第一行為n,m n表示初始序列有n個數,這個序列依次是(1,2……n-1,n) m表示翻轉操作次數
接下來m行每行兩個數[l,r] 資料保證 1<=l<=r<=n
Output
輸出一行n個數字,表示原始序列經過m次變換後的結果
Sample Input
5 31 3
1 3
1 4
Sample Output
4 3 2 1 5HINT
N,M<=100000
Source
普通的區間翻轉而已.
#include<stdio.h> #include<algorithm> using namespace std; const int maxn=100005; int siz[maxn],c[maxn][2],newone,s[maxn],rev[maxn],fa[maxn],n,m,tot,root,l,r,w[maxn]; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline int read(){ register int x=0,f=1; register char ch=nc(); while(ch<'0'||ch>'9'){if(ch=='-')f*=-1;ch=nc();} while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=nc(); return f*x; } inline int newnode(){ newone=++tot; siz[newone]=fa[newone]=c[newone][0]=c[newone][1]=0; return newone; } inline void update(int x){ if(!x) return; siz[x]=siz[c[x][0]]+siz[c[x][1]]+1; } inline void pushdown(int x){ if(!x) return; if(rev[x]){ rev[x]^=1,rev[c[x][0]]^=1,rev[c[x][1]]^=1; swap(c[x][0],c[x][1]); } } inline void rotate(int x,int &_wanna){ int y=fa[x],z=fa[y]; int l=(c[y][0]!=x),r=l^1; if(y!=_wanna) c[z][c[z][0]!=y]=x; else _wanna=x; fa[x]=z,fa[y]=x,fa[c[x][r]]=y; c[y][l]=c[x][r],c[x][r]=y; update(y),update(x); } inline void splay(int x,int &_wanna){ int top=0; for(int i=x;i;i=fa[i]) s[++top]=i; for(int i=top;i;i--) pushdown(s[i]); for(int f;x!=_wanna;rotate(x,_wanna)) if((f=fa[x])!=_wanna) rotate(((c[fa[f]][0]==f^c[f][0]==x)?x:f),_wanna); } int find(int k,int x){ pushdown(k); if(x-1==siz[c[k][0]]) return k; if(x>siz[c[k][0]]+1) return find(c[k][1],x-siz[c[k][0]]-1); else return find(c[k][0],x); } void build(int lf,int rg,int who){ int mid=(lf+rg)>>1; w[who]=mid; if(lf==rg) {siz[who]=1;return;} if(lf<mid) {c[who][0]=newnode();fa[c[who][0]]=who;build(lf,mid-1,c[who][0]);} if(rg>mid) {c[who][1]=newnode();fa[c[who][1]]=who;build(mid+1,rg,c[who][1]);} update(who); } inline void init(){ root=1,tot=2; fa[root]=0,c[root][1]=2,fa[2]=1,c[2][0]=newnode(),fa[c[2][0]]=2; build(1,n,c[2][0]); update(2),update(1); } void dfs(int x){ pushdown(x); if(c[x][0]) dfs(c[x][0]); if(w[x]) printf("%d ",w[x]); if(c[x][1]) dfs(c[x][1]); } int main(){ n=read(),m=read(); init(); while(m--){ l=read(),r=read(); l=find(root,l);splay(l,root); r=find(root,r+2);splay(r,c[l][1]); rev[c[r][0]]^=1; } dfs(root); }