码迷,mamicode.com
首页 > 编程语言 > 详细

【BZOJ】【1552】【Cerc2007】robotic sort / 【3506】【CQOI2014】排序机械臂

时间:2015-04-14 00:19:07      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:

Splay


  离散化+Splay维护序列……

  好吧主要说一下我做这道题遇到的几个错误点:

  1.离散化

  2.由于找到的这个数的位置一定是大于等于 i 的,所以其实在把它splay到根以后,i 结点只能splay到它的左儿子,而不是右儿子……而且相应的,代表这个区间的应该是c[c[root][0]][1]呃……就是root的左儿子的右儿子= =整个反了一下……好吧不要在意这些细节,我也不知道为什么我突然要反过来写[捂脸熊]

  3.进行了修改操作以后一定要立即splay修改的结点!在这题中就是当找到最小结点,将其置为无穷大后,一定要splay一下……否则就WA了TAT

技术分享
  1 /**************************************************************
  2     Problem: 1552
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:2764 ms
  7     Memory:4888 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 1552
 11 #include<cstdio>
 12 #include<cstring>
 13 #include<cstdlib>
 14 #include<iostream>
 15 #include<algorithm>
 16 #define rep(i,n) for(int i=0;i<n;++i)
 17 #define F(i,j,n) for(int i=j;i<=n;++i)
 18 #define D(i,j,n) for(int i=j;i>=n;i--)
 19 using namespace std;
 20 typedef long long LL;
 21 inline int getint(){
 22     int r=1,v=0; char ch=getchar();
 23     for(;!isdigit(ch);ch=getchar()) if (ch==-) r=-1;
 24     for(; isdigit(ch);ch=getchar()) v=v*10+ch-0;
 25     return r*v;
 26 }
 27 const int N=1e5+10,INF=~0u>>2;
 28 /******************template*********************/
 29 struct node{int v,pos;}a[N];
 30 bool operator < (node a,node b){return a.pos<b.pos;}
 31 bool cmp(node a,node b){return a.v<b.v||(a.v==b.v && a.pos<b.pos);}
 32 int c[N][2],fa[N],v[N],mn[N],size[N],tot,root,n;
 33 bool rev[N];
 34 #define L c[x][0]
 35 #define R c[x][1]
 36 void Push_down(int x){
 37     if (rev[x]){
 38         rev[L]^=1; rev[R]^=1;
 39         swap(L,R); rev[x]=0; 
 40     }
 41 }
 42 void Push_up(int x){
 43     mn[x]=v[x];
 44     if (L) mn[x]=min(mn[x],mn[L]);
 45     if (R) mn[x]=min(mn[x],mn[R]);
 46     size[x]=size[L]+size[R]+1;
 47 }
 48 void Rotate(int x){
 49     int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
 50     c[z][c[z][1]==y]=x;
 51     fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
 52     c[y][l]=c[x][r]; c[x][r]=y;
 53     Push_up(y);
 54 }
 55 int st[N];
 56 void Preview(int x){
 57     int top=0; st[++top]=x;
 58     for(int i=x;fa[i];i=fa[i])
 59         st[++top]=fa[i];
 60     D(i,top,1) Push_down(st[i]);
 61 }
 62 void splay(int x,int s=0){
 63     int y;
 64     for(Preview(x);fa[x]!=s;Rotate(x))
 65         if (fa[y=fa[x]]!=s) Rotate(c[y][1]==x^c[fa[y]][1]==y?x:y);
 66     Push_up(x);
 67     if (!s) root=x;
 68 }
 69 void New_node(int &x,int f,int key){
 70     x=++tot;
 71     fa[x]=f;
 72     v[x]=mn[x]=key;
 73     rev[x]=L=R=0;
 74     size[x]=1;
 75 }
 76 void Build(int &x,int f,int l,int r){
 77     if (l>r) return;
 78     int mid=l+r>>1;
 79     New_node(x,f,a[mid].v);
 80     Build(L,x,l,mid-1);
 81     Build(R,x,mid+1,r);
 82     Push_up(x);
 83 }
 84 int kth(int x,int k){
 85     Push_down(x);
 86     if (size[L]+1==k) return x;
 87     else if (size[L]>=k) return kth(L,k);
 88     else return kth(R,k-size[L]-1);
 89 }
 90 int findmin(int x){
 91     Push_down(x);
 92     if (L && mn[x]==mn[L]) return findmin(L);
 93     else if (R && mn[x]==mn[R]) return findmin(R)+size[L]+1;
 94     else {v[x]=INF;Push_up(x); return size[L]+1;}
 95 }
 96 int main(){
 97     n=getint();
 98     v[0]=mn[0]=a[0].v=a[n+1].v=INF;
 99     F(i,1,n) {a[i].v=getint();a[i].pos=i;}
100     sort(a+1,a+n+1,cmp);
101     F(i,1,n) a[i].v=i;
102     sort(a+1,a+n+1);
103     Build(root,0,0,n+1);
104     F(i,1,n){
105         int t1=findmin(root);
106         splay(kth(root,t1));
107         printf("%d",t1-1); if(i!=n)printf(" ");
108         splay(kth(root,t1+1)); splay(kth(root,i),root);
109         int pos=c[c[root][0]][1];
110         if (pos) rev[pos]^=1;
111         splay(pos);
112     }
113     return 0;
114 }
115 
View Code

1552: [Cerc2007]robotic sort

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 436  Solved: 186
[Submit][Status][Discuss]

Description

技术分享

Input

输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。

Output

输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,(1 < = Pi < = N),Pi表示第i次操作前第i小的物品所在的位置。 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。

Sample Input

6
3 4 5 1 6 2

Sample Output

4 6 4 5 6 6

HINT

Source

[Submit][Status][Discuss]

【BZOJ】【1552】【Cerc2007】robotic sort / 【3506】【CQOI2014】排序机械臂

标签:

原文地址:http://www.cnblogs.com/Tunix/p/4423547.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!