排序机械臂
来源:互联网 发布:淘宝关注店铺上新提醒 编辑:程序博客网 时间:2024/05/02 02:14
题目大意
给出一个长度为n的序列a,有n次操作,第i次操作把数值a第i小的位置记作p[i],位置i到p[i]的数反转(如1,2,3,4反转后变成4,3,2,1)。求输出序列p。
范围a[i]<=2*10^9,n<=10^5。
先离散化
裸splay
用splay树维护size。答案p[i]=size[i的左儿子]+1。
对于反转操作,可以打个标记。
代码
#include<cstdio>#include<cstring>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=100000+5;struct ar{ int x,y;} a[maxn];int fa[maxn],b[maxn],size[maxn],tree[maxn][2],re[maxn],q[maxn];int n,i,j;bool cmp(ar a,ar b) { return a.x<b.x||((a.x==b.x)&&(a.y<b.y));}int pd(int x){ if (tree[fa[x]][0]==x) return 0;return 1;}void update(int x) { size[x]=size[tree[x][0]]+size[tree[x][1]]+1;}void clear(int x){ int l=tree[x][0],r=tree[x][1]; if (re[x]==0) return; re[x]=0; re[l]=1-re[l],re[r]=1-re[r]; swap(tree[x][0],tree[x][1]);}void chu(int x,int y){ q[0]=0; while (x!=y){ q[++q[0]]=x; x=fa[x]; } int i; fo(i,1,q[0]) clear(q[q[0]-i+1]);}void rotate(int x){ int y=fa[x],z=pd(x); fa[x]=fa[y]; if (fa[y]) tree[fa[y]][pd(y)]=x; tree[y][z]=tree[x][1-z]; if (tree[x][1-z]) fa[tree[x][1-z]]=y; tree[x][1-z]=y; fa[y]=x; update(y),update(x);}void splay(int x,int y){ chu(x,y); while (fa[x]!=y){ int f=fa[x]; if (fa[f]!=y) if (pd(x)==pd(f)) rotate(f);else rotate(x); rotate(x); }}int kth(int x,int y){ clear(x); if (size[tree[x][0]]+1==y) return x; if (size[tree[x][0]]+1>y) return kth(tree[x][0],y); return kth(tree[x][1],y-size[tree[x][0]]-1);}void split(int x,int y,int &l,int &r){ int j=kth(x,y); splay(j,0); l=j,r=tree[j][1]; tree[l][1]=0; fa[r]=0; update(j);}void merge(int x,int y,int &l){ int j=kth(x,size[x]); splay(j,0); tree[j][1]=y; fa[y]=j; update(j); l=j;}int main(){ scanf("%d",&n); fo(i,1,n) { scanf("%d",&a[i].x); a[i].y=i; } sort(a+1,a+n+1,cmp); fo(i,1,n) b[a[i].y]=i;size[n+1]=size[n+2]=1; tree[b[1]][0]=n+1,fa[n+1]=b[1],update(b[1]); fo(i,2,n) { tree[b[i]][0]=b[i-1]; fa[b[i-1]]=b[i]; update(b[i]); } tree[n+2][0]=b[n],fa[b[n]]=n+2,update(n+2); fo(i,1,n-1){ int l,r,mid; splay(i,0); printf("%d ",size[tree[i][0]]); if (i==n-1) continue; split(i,size[tree[i][0]]+1,l,r); split(l,i,l,mid); re[mid]=1-re[mid]; merge(l,mid,l); merge(l,r,l); } printf("%d",n);}
0 0
- 排序机械臂 <Splay>
- 排序机械臂
- 【CQOI2014】排序机械臂
- BZOJ3506 排序机械臂
- 【CQOI2014】排序机械臂
- 【CQOI2014】排序机械臂
- [CQOI 2014] 排序机械臂
- bzoj3506 [Cqoi2014]排序机械臂
- [BZOJ3506]CQOI2014排序机械臂
- 【bzoj3506】【CQOI2014】排序机械臂
- JZOJ3599【CQOI2014】排序机械臂
- [BZOJ3506][BZOJ1552] [Cqoi2014]排序机械臂
- CQOI2014 排序机械臂--splay膜版题
- 【jzoj3599】【CQOI2014】【排序机械臂】【splay】
- 机械臂
- 【BZOJ】【P1552&3506】【Cqoi2014】【排序机械臂】【题解】【Treap】
- BZOJ 3506 CQOI 2014 排序机械臂 Splay
- BZOJ3506 [Cqoi2014]排序机械臂(离散化+Splay)
- 21PL_SQL过程之函数
- Java NIO使用及原理分析
- Java线程操作
- C语言基础 输入球的半径,求出球的表面积及体积
- Email Header 是什么
- 排序机械臂
- 七牛选择华北简单上传抛出的异常 error:incorrect zone, please use up-z1.qiniu.com
- 苹果_ssl1637_dp
- Codeforces Round #359 (Div. 2) B. Little Robber Girl's Zoo(水题)
- ocupload、struts2实现excel文件上传,poi解析
- C语言基础 输入直角坐标系上的两个点,计算它们的之间的距离
- Struts 2中的constant详解
- 设计模式 I ——简单工厂模式(Factory)
- linux系统ln命令的用法