6 3 4 5 1 6 2 4 3 3 2 1 0
4 6 4 5 6 6 4 2 4 4
————————————————————————分割线————————————————————
题目大意:
对你一个序列,每次将第i个位置到第i大的数所在位置 之间的数进行翻转,输出第i大的数所在的位置
思路:
对序列离散化为1~n,然后用个数组存储权值为i,在伸展树中的节点号为rt,mp[x]=rt;
从小到大将权值为i(第i大),节点编号为mp[i]旋转到根,那么这个数在序列中的位置就是i+size[ch[root][0]],然后标记rev
注意点:
不用新建边界点,否则在翻转操作会把边界点也一起翻转,导致错误
写得蛋碎,自己太弱了....
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cstdlib> #define REP(i,n) for(int i=0;i<(n);++i) #define Key_value ch[ch[root][1]][0] #define lson ch[rt][0] #define rson ch[rt][1] const int maxn=100010; using namespace std; int n; struct node { int x; int id; bool operator<(const node&cmp) const{ return ((x<cmp.x)||(x==cmp.x&&id<cmp.id)); } } a[maxn]; struct SplayTree{ int root,tot; int ch[maxn][2],pre[maxn],rev[maxn],size[maxn]; int dis[maxn],mp[maxn],key[maxn]; void update_rev(int rt) { if(!rt) return; swap(lson,rson); rev[rt]^=1; } void push_up(int rt) { size[rt]=size[lson]+size[rson]+1; } void push_down(int rt) { if(rev[rt]) { update_rev(lson); update_rev(rson); rev[rt]=0; } } void NewNode(int &rt,int f) { rt=++tot; lson=rson=0; pre[rt]=f; size[rt]=1; rev[rt]=0; } void build(int &rt,int l,int r,int f) { if(l>r) return ; int m=(l+r)>>1; // cout<<dis[m]<<endl; NewNode(rt,f); mp[dis[m]]=rt; build(lson,l,m-1,rt); build(rson,m+1,r,rt); push_up(rt); } void Init() { root=tot=0; ch[0][0]=ch[0][1]=pre[0]=size[0]=rev[0]=0; NewNode(root,0); NewNode(ch[root][1],root); REP(i,n) { scanf("%d",&a[i].x);a[i].id=i; } sort(a,a+n); REP(i,n) dis[a[i].id]=i; mp[dis[0]]=1;//注意这两个操作,没有新建边界端点;如果没有,那么翻转的时候会把边界端点也翻转,导致错误!!! mp[dis[n-1]]=2;// build(Key_value,1,n-2,ch[root][1]); push_up(ch[root][1]); push_up(root); } 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; 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) { Rotate(x,ch[pre[x]][0]==x); } else { int y=pre[x]; int kind=ch[pre[y]][0]==y; 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 RotateTo(int k,int goal) { int rt=root; push_down(rt); while(size[lson]+1!=k) { if(size[lson]>=k) rt=lson; else { k-=(size[lson]+1); rt=rson; } push_down(rt); } Splay(rt,goal); } int Get_kth(int rt,int k) { push_down(rt); int t=size[lson]+1; if(t==k) return rt; if(t>k) return Get_kth(lson,k); else return Get_kth(rson,k-t); } void del_root() { if(ch[root][1]) { int t=root; root=ch[root][1]; // RotateTo(1,0); ch[root][0]=ch[t][0]; if(ch[t][0]) pre[ch[t][0]]=root; } else root=ch[root][0]; pre[root]=0; push_up(root); } void solve() { REP(i,n) { Splay(mp[i],0); if(i>0) printf(" "); printf("%d",size[ch[root][0]]+i+1); update_rev(ch[root][0]); del_root(); // cnt=0;InOrder(root);puts(""); } puts(""); } }spt; int main() { while(scanf("%d",&n),n) { if(n==1) {scanf("%*d");printf("1\n");continue;} spt.Init(); spt.solve(); } return 0; }