bzoj3223 文艺平衡树 (treap or splay分裂+合并)
3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3313 Solved: 1883
[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 3
1 3
1 3
1 4
1 3
1 3
1 4
Sample Output
4 3 2 1 5
HINT
N,M<=100000
Source
RunID
User | Problem | Result | Memory | Time | Language | Code_Length | Submit_Time | |
1538282 | ksq2013 | 3223 | Accepted | 5396 kb | 2576 ms | C++/Edit | 2878 B | 2016-07-08 20:57:17 |
区间翻转裸题,废话不多说,直接放代码:
#include<cstdio> #include<iostream> #define INF 0x3f3f3f3f #define Key_value ch[ch[root][1]][0] using namespace std; bool rev[200100]; int n,m,root,tot,size[200100],key[200100],pre[200100],ch[200100][2]; void NewNode(int &x,int father,int val) { x=++tot; size[x]=1; key[x]=val; pre[x]=father; } void Update_Rev(int x) { rev[x]^=1; swap(ch[x][0],ch[x][1]); } void Push_Up(int x) { size[x]=size[ch[x][0]]+size[ch[x][1]]+1; } void Push_Down(int x) { if(rev[x]){ Update_Rev(ch[x][0]); Update_Rev(ch[x][1]); rev[x]=0; } } void build(int &x,int father,int l,int r) { if(l>r)return; int mid=(l+r)>>1; NewNode(x,father,mid); build(ch[x][0],x,l,mid-1); build(ch[x][1],x,mid+1,r); Push_Up(x); } void Init() { NewNode(root,0,INF); NewNode(ch[root][1],root,INF); build(Key_value,ch[root][1],1,n); } int Get_Kth(int x,int k) { Push_Down(x);//mistaken codes; int t=size[ch[x][0]]+1; if(t==k)return x; if(t>k)return Get_Kth(ch[x][0],k); return Get_Kth(ch[x][1],k-t); } void Rotate(int x,int kind) { int y=pre[x]; Push_Down(y);Push_Down(x); ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;//unfixed; pre[x]=pre[y]; ch[x][kind]=y; pre[y]=x; Push_Up(y); } void Splay(int x,int goal) { Push_Down(x); while(pre[x]!=goal){ if(pre[pre[x]]==goal){ Push_Down(pre[x]); Push_Down(x); Rotate(x,ch[pre[x]][0]==x); } else{ int y=pre[x]; int kind=ch[pre[y]][0]==y; Push_Down(pre[y]);//mistaken codes&&一遇到向下的操作就Push_Down; Push_Down(y);//mistaken codes Push_Down(x);//mistaken codes if(ch[y][kind]==x){ Rotate(x,!kind); Rotate(x,kind); } else{ Rotate(y,kind); Rotate(x,kind); } } } Push_Up(x); if(goal==0)root=x; } void Rev(int l,int r) { Splay(Get_Kth(root,l),0); Splay(Get_Kth(root,r+2),root); Update_Rev(Key_value); Push_Up(ch[root][1]); Push_Up(root); } void dfs(int x) { if(!x)return; Push_Down(x); dfs(ch[x][0]); if(1<=key[x]&&key[x]<=n)printf("%d ",key[x]); dfs(ch[x][1]); } int main() { scanf("%d%d",&n,&m); Init(); for(int x,y;m;m--){ scanf("%d%d",&x,&y); Rev(x,y); }dfs(root); return 0; }
新splay模板上线,更简洁
#include<stdio.h> #include<stdlib.h> #include<limits.h> inline int Rin(){ int x=0,c=getchar(),f=1; for(;c<48||c>57;c=getchar()) if(!(c^45))f=-1; for(;c>47&&c<58;c=getchar()) x=(x<<1)+(x<<3)+c-48; return x*f; } struct node{ node*ch[2]; int r,s,v;bool b; node (int v,node*k):v(v){ r=rand(); b=0;s=1; ch[0]=ch[1]=k; } void exc(node*&x,node*&y) {node*k=y;y=x;x=k;} void pu(){s=ch[0]->s+ch[1]->s+1;} void pd(){ if(b){ b=0; exc(ch[0],ch[1]); ch[0]->b^=1; ch[1]->b^=1; } } }*rt,*bf; inline void rot(node*&o,int d){ node*k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o; o->pu();k->pu();o=k; } inline int cmk(node*o,int k){ if(o->ch[0]->s+1==k)return -1; if(o->ch[0]->s>=k)return 0; return 1; } inline void ins(node*&o,int x){ if(o==bf){o=new node(x,bf);return;} ins(o->ch[1],x); o->ch[1]->r>o->r?rot(o,0):o->pu(); } inline void splay(node*&o,int k){ if(o==bf)return; o->pd();int d=cmk(o,k); if(!(d^1))k-=o->ch[0]->s+1; if(d!=-1&&o->ch[d]!=bf){ node*p=o->ch[d];p->pd(); int dd=cmk(p,k); if(dd!=-1&&p->ch[dd]!=bf){ int kk=(dd?k-p->ch[0]->s-1:k); splay(p->ch[dd],kk); d^dd?rot(o->ch[d],d):rot(o,d^1); } rot(o,d^1); } } inline node*mrg(node*l,node*r){ splay(l,l->s);l->ch[1]=r; l->pu();return l; } inline void slt(node*o,int k,node*&l,node*&r){ if(!k){l=bf;r=o;return;} if(!(k^o->s)){l=o;r=bf;return;} splay(o,k);l=o;r=o->ch[1]; o->ch[1]=bf;l->pu(); } inline void ini(){ bf=new node(0,0); bf->r=INT_MAX;bf->s=bf->v=0; bf->ch[0]=bf->ch[1]=bf;rt=bf; ins(rt,0);rt->r=-999; } void opt(node*o){ if(o==bf)return; o->pd(); opt(o->ch[0]); if(o->r!=-999)printf("%d ",o->v); opt(o->ch[1]); } int n,m; int main(){ n=Rin(),m=Rin();ini(); for(int i=1;i<=n;i++)ins(rt,i); while(m--){ int l=Rin(),r=Rin(); node *ll,*rr,*mm; slt(rt,l,ll,rr); slt(rr,r-l+1,mm,rr); mm->b^=1; rt=mrg(mrg(ll,mm),rr); } opt(rt); return 0; }