bzoj1552&3506 robotic sort

这道题提醒了我:

1、交之前要删文件

2、v不要打成mn

3、maintain的位置

4、pushdown pushdown pushdown

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 #define rep(i,l,r) for(int i=l;i<r;i++)
  8 #define clr(a,s) memset(a,x,sizeof(a))
  9 using namespace std;
 10 int read()
 11 {
 12     int ans=0;
 13     char c=getchar();
 14     while(!isdigit(c)) c=getchar();
 15     while(isdigit(c)){
 16         ans=ans*10+c-‘0‘;
 17         c=getchar();
 18     }
 19     return ans;
 20 }
 21 const int maxn=100005,inf=0x3fffffff;
 22 struct node*null,*pt;
 23 struct node{
 24     int v,s,mn;
 25     bool rev;
 26     node*ch[2];
 27     inline int cmp(int k) const{
 28         k-=ch[0]->s;
 29         if(k==1) return -1;
 30         return k<=0?0:1;
 31     }
 32     inline void maintain(){
 33         s=ch[0]->s+ch[1]->s+1;
 34         mn=min(v,min(ch[0]->mn,ch[1]->mn));
 35     }
 36     inline void pushdown(){
 37         if(rev){
 38             rev=0;
 39             ch[0]->rev^=1;
 40             ch[1]->rev^=1;
 41             swap(ch[0],ch[1]);
 42         }
 43     }
 44 };
 45 void rotate(node*&o,int d)
 46 {
 47     node*k=o->ch[d^1];
 48     o->ch[d^1]=k->ch[d];
 49     k->ch[d]=o;
 50     o->maintain();k->maintain();
 51     o=k;
 52 }
 53 void splay(node*&o,int k)
 54 {
 55     o->pushdown();
 56     int d=o->cmp(k);
 57     if(d==-1) return;
 58     if(d==1) k-=o->ch[0]->s+1;
 59     node*p=o->ch[d];
 60     p->pushdown();
 61     int d2=p->cmp(k);
 62     int k2=(d2?k-p->ch[0]->s-1:k);
 63     if(d2!=-1){
 64         splay(p->ch[d2],k2);
 65         d==d2?rotate(o,d^1):rotate(o->ch[d],d);
 66     }
 67     rotate(o,d^1);
 68 }
 69 struct num{
 70     int v,r;
 71     inline bool operator <(const num&an)const{
 72         return (v<an.v)||(v==an.v&&r<an.r);
 73     }
 74 };
 75 node*newnode(int k)
 76 {
 77     pt->ch[0]=null;
 78     pt->ch[1]=null;
 79     pt->v=pt->mn=k;
 80     pt->rev=0;
 81     pt->s=1;
 82     return pt++;
 83 }
 84 num a[maxn];
 85 int b[maxn];
 86 node*build(int l,int r)
 87 {
 88     if(l>=r) return null;
 89     int mid=(l+r)>>1;
 90     node*o=newnode(b[mid]);
 91     if(l<mid) o->ch[0]=build(l,mid);
 92     if(mid+1<r) o->ch[1]=build(mid+1,r);
 93     o->maintain();
 94     return o;
 95 }
 96 int cnt=0;
 97 void dfs(node*o)
 98 {
 99     if(o==null) return;
100     o->pushdown();
101     dfs(o->ch[0]);
102     printf("%d ",o->v);
103     dfs(o->ch[1]);
104 }
105 int find(node*o,int k)
106 {
107     o->pushdown();
108     if(o->v==k) return o->ch[0]->s+1;
109     if(o->ch[0]->mn==k) return find(o->ch[0],k);
110     return find(o->ch[1],k)+o->ch[0]->s+1;
111 }
112 int n,ans[maxn];
113 node x[maxn],*root;
114 void init()
115 {
116     pt=x;
117     null=newnode(inf);
118     null->s=0;
119     root=build(0,n+2);
120 }
121 int main()
122 {
123     n=read();
124     rep(i,0,n){
125         a[i].v=read();
126         a[i].r=i;
127     }
128     sort(a,a+n);
129     rep(i,0,n) b[a[i].r+1]=i+1;
130     b[n+1]=inf;
131     b[0]=inf;
132     init();
133     rep(i,1,n+1){
134         splay(root,i);
135         ans[i]=find(root,i);
136         printf("%d",ans[i]-1);
137         if(i!=n) printf(" ");
138         splay(root->ch[1],ans[i]-root->ch[0]->s);
139         root->ch[1]->ch[0]->rev^=1;
140     }
141     return 0;
142 } 

1552: [Cerc2007]robotic sort

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 486  Solved: 203
[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

HNOI2009集训Day6

时间: 2024-10-19 23:53:27

bzoj1552&3506 robotic sort的相关文章

[BZOJ1552][Cerc2007]robotic sort

试题描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. 输出 输出共一行,N个用空格隔开的正整数P1,P2,P3-Pn,Pi表示第i次操作前第i小的物品所在的位置. 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品). 输入示例 6 3 4 5 1 6 2 输出示例 4 6 4 5 6 6 数据规模及约定 见"输入" 题解 暴力

[bzoj1552][Cerc2007]robotic sort&amp;&amp;[bzoj3506][Cqoi2014]排序机械臂

非常垃圾的一道平衡树,结果被日了一天.很难受嗷嗷嗷 首先不得不说网上的题解让我这个本来就不熟悉平衡树的彩笔很难受--并不好理解. 还好Sinogi大佬非常的神,一眼就切掉了,而且用更加美妙的解法. 题意在操作时,就是第i次把编号为i-1和编号i的后继分别提到根和根的右儿子,根的右儿子的左子树打上翻转标记. 用外部数组记录原来高度第几大的在平衡树中编号是多少.就可以直接操作了. 注意有相同的高度,离散化时直接按高度第一关键字,编号第二关键字就行了. 还有每次splay要把根到当前节点都pushdo

【bzoj1552/3506】[Cerc2007]robotic sort splay翻转,区间最值

[bzoj1552/3506][Cerc2007]robotic sort 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]

【BZOJ-1552&amp;3506】robotic sort&amp;排序机械臂 Splay

1552: [Cerc2007]robotic sort Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 806  Solved: 329[Submit][Status][Discuss] Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. Output 输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,Pi表示第i次操作

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

Splay 离散化+Splay维护序列…… 好吧主要说一下我做这道题遇到的几个错误点: 1.离散化 2.由于找到的这个数的位置一定是大于等于 i 的,所以其实在把它splay到根以后,i 结点只能splay到它的左儿子,而不是右儿子……而且相应的,代表这个区间的应该是c[c[root][0]][1]呃……就是root的左儿子的右儿子= =整个反了一下……好吧不要在意这些细节,我也不知道为什么我突然要反过来写[捂脸熊] 3.进行了修改操作以后一定要立即splay修改的结点!在这题中就是当找到最小结

BZOJ 1552: [Cerc2007]robotic sort( splay )

kpm大神说可以用块状链表写...但是我不会...写了个splay.... 先离散化 , 然后splay结点加个min维护最小值 , 就可以了... ( ps BZOJ 3506 题意一样 , 双倍经验 ) ----------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #inclu

bzoj 1552: [Cerc2007]robotic sort.

1552: [Cerc2007]robotic sort Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1211  Solved: 463[Submit][Status][Discuss] Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000. 第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. Output 输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,Pi表示第i次

hdu 1890 Robotic Sort(splay 区间反转+删点)

题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的splay区间翻转+删点. 我们把数据排序,然后记录一下每个数原来的位置,然后splay建树的时候用原来的位置来对应,这样val[i].second就直接是这个数在splay中的那个节点. (当然你也可以普通建树,然后手动记录位置). 然后我们把要找的那个数对应的节点旋转到根,然后根左边的size+i就

数据结构(Splay平衡树):HDU 1890 Robotic Sort

Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3456    Accepted Submission(s): 1493 Problem Description Somewhere deep in the Czech Technical University buildings, there are labora