SGU 187.Twist and whirl - want to cheat
splay
不过竟然用reverse一发水过了。。。
调用STL的代码:(156ms)
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; int f[130009]; int n,m,l,r; int main(){ scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=m;i++){ scanf("%d %d",&l,&r); reverse(f+l,f+r+1); } for(int i=1;i<=n;i++) printf("%d ",f[i]); }
Splay(46ms)(代码来自网络)
#include<cstdio> #include<algorithm> const int MAXn=130000+9; struct splay_tree { int l[MAXn],r[MAXn],f[MAXn],n,root; int size[MAXn]; bool re[MAXn]; void push(int u) { if(re[u]) { re[u]=0; if(l[u]) re[l[u]]^=1; if(r[u]) re[r[u]]^=1; std::swap(l[u],r[u]); } } void update(int u) { size[u]=size[l[u]]+size[r[u]]+1; } void rotate(int x) { int y=f[x]; push(y); push(x); f[x]=f[y]; if(f[y]) { if(l[f[y]]==y) l[f[y]]=x; else r[f[y]]=x; } f[y]=x; if(x==r[y]) { if(l[x]) f[l[x]]=y; r[y]=l[x]; l[x]=y; } else { if(r[x]) f[r[x]]=y; l[y]=r[x]; r[x]=y; } update(y); update(x); } void splay(int u,int aim) { int t; while((t=f[u])!=aim) if(f[t]==aim) rotate(u); else if((l[f[t]]==t)==(l[t]==u)) rotate(t),rotate(u); else rotate(u),rotate(u); if(!aim) root=u; } void build(int num) { size[0]=0; re[0]=0; n=num; root=1; for(int i=1;i<=n;++i) { l[i]=0; r[i]=i+1; f[i]=i-1; size[i]=n-i+1; re[i]=0; } r[n]=0; splay(n,0); } int find(int rank) { if(!rank || rank>n) return 0; for(int u=root;;) { push(u); if(size[l[u]]+1==rank) { splay(u,0); return u; } else if(rank<=size[l[u]]) u=l[u]; else { rank-=size[l[u]]+1; u=r[u]; } } } void reserve(int a,int b) { int pre=find(a-1),suf=find(b+1); if(pre) { splay(pre,0); if(suf) { splay(suf,pre); re[l[suf]]^=1; } else re[r[pre]]^=1; } else if(suf) { splay(suf,0); re[l[suf]]^=1; } else re[root]^=1; } void print(int u) { for(;u;u=r[u]) { push(u); print(l[u]); printf("%d ",u); } } }tree; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin);freopen("out.txt","w",stdout); #endif int n,m,i,j,k; scanf("%d%d",&n,&m); tree.build(n); for(i=1;i<=m;++i) { scanf("%d%d",&j,&k); tree.reserve(j,k); } tree.print(tree.root); return 0; }