题目描述 Description
给出N个数,要求做M次区间翻转(如1 2 3 4变成4 3 2 1),求出最后的序列
输入描述 Input Description
第一行一个数N,下一行N个数表示原始序列,在下一行一个数M表示M次翻转,之后的M行每行两个数L,R表示将区间[L,R]翻转。
输出描述 Output Description
一行N个数 , 表示最终序列。
样例输入 Sample Input
4
1 2 3 4
2
1 2
3 4
样例输出 Sample Output
2 1 4 3
数据范围及提示 Data Size & Hint
对于30%的数据满足n<=100 , m <= 10000
对于100%的数据满足n <= 150000 , m <= 150000
对于100%的数据满足n为2的幂,且L = i * 2^j + 1 , R = (i + 1) * 2^j
最初自己写了一个,然后怎么调也调不出来,明天再战:
#include<cstdio> #include<iostream> #define N 150010 using namespace std; int son[N][2],fa[N],val[N],order[N],rev[N],sz[N],n,m,rt,size; void pushup(int x){ if(!x)return; sz[x]=sz[son[x][0]]+sz[son[x][1]]+1; } void pushdown(int x){ swap(son[x][0],son[x][1]); rev[son[x][0]]^=1;rev[son[x][1]]^=1; rev[x]^=1; } void rotate(int x,int &k){ int y=fa[x],z=fa[y],l,r; if(son[y][0]==x)l=0;else l=1;r=l^1; if(y==k)k=x; else { if(son[z][0]==y) son[z][0]=x; else son[z][1]=x; } fa[x]=z;fa[y]=x;fa[son[x][r]]=y; son[y][l]=son[x][r];son[x][r]=y; pushup(y);pushup(x); } void splay(int x,int &k){ while(x!=k){ int y=fa[x],z=fa[y]; if(y!=k){ if((son[y][0]==x)^(son[z][0]==y)) rotate(x,k); else rotate(y,k); } rotate(x,k); } } void insert(int hao,int v){ int k=rt,y=0; while(k)y=k,k=son[k][hao>order[k]]; k=++size;fa[k]=y;son[y][v>order[y]]=k;val[k]=v;order[k]=hao;sz[k]=1; splay(k,rt); } int find(int x){ int k=rt; while(1){ if(rev[k])pushdown(k); if(sz[son[k][0]]+1==x)return k; if(sz[son[k][0]]>=x) k=son[k][0]; else x-=(sz[son[k][0]]+1),k=son[k][1]; } } void rever(int x,int y){ if(x==1&&y==n)rev[rt]^=1; if(x==1&&y<n){ int p=find(y+1); splay(p,rt);rev[son[rt][0]]^=1; } if(y==n&&x>1){ int p=find(x-1); splay(p,rt);rev[son[rt][1]]^=1; } if(x>1&&y<n){ int p; p=find(x-1);splay(p,rt); p=find(y+1);splay(p,son[rt][1]); rev[son[son[rt][1]][0]]^=1; } } void dfs(int k){ if(!k)return; if(rev[k])pushdown(k); dfs(son[k][0]); printf("%d ",val[k]); dfs(son[k][1]); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ int x;scanf("%d",&x); insert(i,x); } scanf("%d",&m); for(int i=1;i<=m;i++){ int x,y;scanf("%d%d",&x,&y); //if(i==1)continue; rever(x,y); } dfs(rt); return 0; }
比着黄学长写了一个:
#include<cstdio> #include<iostream> #define N 150010 using namespace std; int fa[N],son[N][2],id[N],sz[N],rev[N],val[N]; int n,m,size,rt; void pushup(int k){ int l=son[k][0],r=son[k][1]; sz[k]=sz[l]+sz[r]+1; } void pushdown(int k){ int l=son[k][0],r=son[k][1]; if(rev[k]){ swap(son[k][0],son[k][1]); rev[l]^=1;rev[r]^=1; rev[k]=0; } } void rotate(int x,int &k){ int y=fa[x],z=fa[y],l,r; if(son[y][0]==x)l=0;else l=1;r=l^1; if(y==k)k=x; else { if(son[z][0]==y) son[z][0]=x; else son[z][1]=x; } fa[x]=z;fa[y]=x;fa[son[x][r]]=y; son[y][l]=son[x][r];son[x][r]=y; pushup(y);pushup(x); } void splay(int x,int &k){ while(x!=k){ int y=fa[x],z=fa[y]; if(y!=k){ if((son[y][0]==x)^(son[z][0]==y)) rotate(x,k); else rotate(y,k); } rotate(x,k); } } int find(int k,int rank){ pushdown(k); int l=son[k][0],r=son[k][1]; if(sz[l]+1==rank)return k; else if(sz[l]>=rank) return find(l,rank); else return find(r,rank-sz[l]-1); } void rever(int l,int r){ int x=find(rt,l),y=find(rt,r+2); splay(x,rt);splay(y,son[x][1]); int z=son[y][0];rev[z]^=1; } void build(int l,int r,int f){ if(l>r)return; int now=id[l],last=id[f]; if(l==r){ fa[now]=last;sz[now]=1; if(l<f)son[last][0]=now; else son[last][1]=now; return; } int mid=l+r>>1;now=id[mid]; build(l,mid-1,mid);build(mid+1,r,mid); fa[now]=last;pushup(mid); if(mid<f)son[last][0]=now; else son[last][1]=now; } int main(){ scanf("%d",&n); for(int i=1;i<=n+2;i++) id[i]=++size; val[1]=-0x7fffffff;val[n+1]=0x7fffffff; for(int i=2;i<=n+1;i++) scanf("%d",&val[i]); build(1,n+2,0);rt=(n+3)>>1; scanf("%d",&m); for(int i=1;i<=m;i++){ int l,r;scanf("%d%d",&l,&r); rever(l,r); } for(int i=2;i<=n+1;i++) printf("%d ",val[find(rt,i)]); return 0; }