您的位置:首页 > 其它

【BZOJ】3506 [Cerc2007]robotic sort Splay

2018-01-11 11:55 309 查看
题目传送门

这好像是两天前的题目了……一直都忘记写blog了……

其实这题就是一道序列翻转+求区间最小值的位置,直接splay维护序列就行了。

p.s.这是一道双倍经验题,不过3506那题的题目描述极为险恶……(见oj1552)……

附上AC代码:

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;

const int N=1e5+10;
struct note{
int w,wz;
bool operator < (const note lyf) const {return wz<lyf.wz;}
}a
;
int n,w
,ch
[2],f
,wz
,sz
,rt,mk
,ans
,size;

inline char nc(void){
static char ch[100010],*p1=ch,*p2=ch;
return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;
}

inline void read(int &a){
static char c=nc();int f=1;
for (;!isdigit(c);c=nc()) if (c=='-') f=-1;
for (a=0;isdigit(c);a=(a<<3)+(a<<1)+c-'0',c=nc());
return (void)(a*=f);
}

inline bool cmp(note p,note q){return p.w<q.w||(p.w==q.w&&p.wz<q.wz);}

#define mid (l+r>>1)
inline void updata(int x){
wz[x]=x;
if (w[wz[ch[x][0]]]<w[wz[x]]) wz[x]=wz[ch[x][0]];
if (w[wz[ch[x][1]]]<w[wz[x]]) wz[x]=wz[ch[x][1]];
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
}
inline void build(int l,int r,int fa){
if (l>r) return;
if (l==r){
f[l]=fa,sz[l]=1,w[l]=a[l].w,wz[l]=l;
return (void)(l<fa?ch[fa][0]=l:ch[fa][1]=l);
}
build(l,mid-1,mid),build(mid+1,r,mid);
f[mid]=fa,w[mid]=a[mid].w,updata(mid);
return (void)(mid<fa?ch[fa][0]=mid:ch[fa][1]=mid);
}
inline void rotate(int x){
int y=f[x],op=(x==ch[y][1]);
ch[y][op]=ch[x][op^1];
if (ch[x][op^1]) f[ch[x][op^1]]=y;
if (f[x]=f[y]) ch[f[y]][ch[f[y]][1]==y]=x;
return f[y]=x,ch[x][op^1]=y,updata(y),updata(x);
}
inline void push(int x){if (mk[x]) mk[x]^=1,mk[ch[x][0]]^=1,mk[ch[x][1]]^=1,swap(ch[x][0],ch[x][1]);}
inline void splay(int x,int ed){
static int top,sk
;sk[top=1]=x;
for (int i=x; i!=ed; i=f[i]) sk[++top]=i;
while (top) push(sk[top--]);
for (int fa=f[x]; fa!=ed; rotate(x),fa=f[x])
if (f[fa]!=ed) rotate((x==ch[fa][0])==(fa==ch[f[fa]][0])?fa:x);
if (!ed) rt=x;
}
inline int find(int x,int k){
if (mk[x]) push(x);
if (sz[ch[x][0]]+1==k) return x;
if (sz[ch[x][0]]>=k) return find(ch[x][0],k);
return find(ch[x][1],k-sz[ch[x][0]]-1);
}
inline int query(int x,int y){
int l=find(rt,x),r=find(rt,y+2);
return splay(l,0),splay(r,rt),wz[ch[ch[rt][1]][0]];
}
inline void rever(int x,int y){
int l=find(rt,x),r=find(rt,y+2);
splay(l,0),splay(r,rt),mk[ch[ch[rt][1]][0]]^=1;
}

int main(void){
read(n),a[1].w=a[n+2].w=2e9,w[0]=2e9;
for (int i=2; i<=n+1; ++i) read(a[i].w),a[i].wz=i;
sort(a+2,a+2+n,cmp);
for (int i=2; i<=n+1; ++i) a[i].w=i-1;
sort(a+2,a+2+n),build(1,n+2,0),rt=(n+3)>>1;
for (int i=1; i<=n; ++i){
int x=query(i,n);
splay(x,0),ans[i]=sz[ch[x][0]],rever(i,ans[i]);
}
for (int i=1; i<n; ++i) printf("%d ",ans[i]);
return printf("%d",ans
),0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: