bzoj 1552
Posted zhangleo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1552相关的知识,希望对你有一定的参考价值。
首先用splay维护嘛
然后查询的时候就把对应的节点转到根,左子树大小就是排名
然后再做个区间翻转即可
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <queue> #include <stack> using namespace std; struct node int v,num; friend bool operator < (node a,node b) return a.v==b.v?a.num<b.num:a.v<b.v; p[100005]; int ch[100005][2]; int siz[100005]; int a[100005]; int f[100005]; int fl[100005]; int rot; int n; void pushdown(int x) if(fl[x]) swap(ch[ch[x][0]][0],ch[ch[x][0]][1]),fl[ch[x][0]]^=1; swap(ch[ch[x][1]][0],ch[ch[x][1]][1]),fl[ch[x][1]]^=1; fl[x]=0; void update(int x) siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; void rotate(int x) int y=f[x],z=f[y],k=(ch[y][1]==x); ch[z][ch[z][1]==y]=x,f[x]=z; ch[y][k]=ch[x][!k],f[ch[x][!k]]=y; ch[x][!k]=y,f[y]=x; update(y),update(x); void dfs_pushdown(int x) if(!x)return; dfs_pushdown(f[x]); pushdown(x); void splay(int x,int ed) dfs_pushdown(x); while(f[x]!=ed) int y=f[x],z=f[y]; if(z!=ed) if((ch[y][1]==x)^(ch[z][1]==y))rotate(x); else rotate(y); rotate(x); if(!ed)rot=x; int get_pos(int x,int k) pushdown(x); if(siz[ch[x][0]]>=k)return get_pos(ch[x][0],k); else if(siz[ch[x][0]]+1<k)return get_pos(ch[x][1],k-1-siz[ch[x][0]]); else return x; int split(int l,int r) int v1=get_pos(rot,l-1),v2=get_pos(rot,r+1); splay(v1,0),splay(v2,v1); return ch[v2][0]; void rever(int l,int r) int p=split(l,r); swap(ch[p][0],ch[p][1]),fl[p]^=1; int buildtree(int l,int r,int fa) int mid=(l+r)>>1; f[a[mid]]=a[fa]; fl[a[mid]]=0; if(l==r)fl[a[mid]]=0;ch[a[mid]][0]=ch[a[mid]][1]=0;siz[a[mid]]=1;return a[mid]; if(l<mid)ch[a[mid]][0]=buildtree(l,mid-1,mid); else ch[a[mid]][0]=0; if(r>mid)ch[a[mid]][1]=buildtree(mid+1,r,mid); else ch[a[mid]][1]=0; update(a[mid]); return a[mid]; int query(int x) splay(x,0); return siz[ch[x][0]]; int main() while(1) scanf("%d",&n); if(!n)return 0; for(int i=1;i<=n;i++)scanf("%d",&p[i].v),p[i].num=i; sort(p+1,p+n+1); for(int i=1;i<=n;i++)a[p[i].num+1]=i+1; a[1]=1,a[n+2]=n+2; rot=buildtree(1,n+2,0); for(int i=1;i<=n;i++) int t=query(i+1); if(t>i)rever(i+1,t+1); printf("%d ",t); printf("\n"); return 0;
以上是关于bzoj 1552的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1552: [Cerc2007]robotic sort
bzoj 1552: [Cerc2007]robotic sort.
BZOJ1552: [Cerc2007]robotic sort
[BZOJ1552][Cerc2007]robotic sort