bzoj 1552: [Cerc2007]robotic sort


1552: [Cerc2007]robotic sort

Time Limit:5 SecMemory Limit:64 MB
Submit:1198Solved:457
[Submit][Status][Discuss]

Description

Input

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

Output

输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,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

splay区间反转
#include<cstdio>
#include<algorithm>
using namespace std;
#define INF 0x7fffffff
int n;
const int maxn = 100020;
struct Data{
    int a,pos;
    bool operator < (const Data & q)const {
        if(q.a==a)return pos<q.pos;
        else return a<q.a;    
    }
}l[maxn];
int mn[maxn],size[maxn],root,data[maxn],ch[maxn][2],mnpos[maxn];
int rev[maxn],fa[maxn];
inline void pushdown(int x)
{
    rev[x]=0;
    rev[ch[x][0]]^=1;
    rev[ch[x][1]]^=1;
    swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
    swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
}
inline void pushup(int x)
{
    mn[x]=min(data[x],min(mn[ch[x][1]],mn[ch[x][0]]));
    if(mn[x]==data[x])mnpos[x]=x;
    else if(mn[x]==mn[ch[x][0]])mnpos[x]=mnpos[ch[x][0]];
    else mnpos[x]=mnpos[ch[x][1]];
    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
inline int getkth(int k,int rt)
{
    if(rev[rt])pushdown(rt);
    if(k==size[ch[rt][0]]+1)return rt;
    if(k<size[ch[rt][0]]+1)return getkth(k,ch[rt][0]);
    else getkth(k-size[ch[rt][0]]-1,ch[rt][1]);
}

inline int son(int x){
    return ch[fa[x]][1]==x;
}
void rotate(int x)
{
    int y=fa[x],z=fa[y],b=son(x),c=son(y),a=ch[x][!b];
    if(z)ch[z][c]=x;else root=x;fa[x]=z;
    if(a)fa[a]=y;ch[y][b]=a;
    ch[x][!b]=y;fa[y]=x;
    pushup(y),pushup(x);
}
void splay(int &x,int i) {
    while(fa[x]!=i)
    {
        int y=fa[x],z=fa[y];
        if(z==i){
            rotate(x);
        }else {
            if(rev[z])pushdown(z);if(rev[y])pushdown(y);if(rev[x])pushdown(x);
            if(son(x)==son(y)) {
                rotate(y),rotate(x);
            }
            else {
                rotate(x);rotate(x);
            }
        }
    }
}
int getmnpos(int l,int r)
{
    int ll=getkth(l-1,root);
    int rr=getkth(r+1,root);
    splay(ll,0);
    splay(rr,ll);
    return mnpos[ch[rr][0]];
}
inline void reverse(int l,int r)
{
    int ll=getkth(l-1,root),rr=getkth(r+1,root),p;
    splay(ll,0);splay(rr,ll);
    p=ch[rr][0];rev[p]^=1;
    swap(ch[p][0],ch[p][1]);
}
int main() {
    scanf("%d",&n);
    for(int i=2;i<=n+1;i++) scanf("%d",&l[i].a),l[i].pos=i;
    sort(l+2,l+n+2);
    for(int i=2;i<=n+1;i++)data[l[i].pos]=i;
    for(int i=0;i<=n+2;i++)mn[i]=INF;
    data[0]=data[1]=data[n+2]=INF;root=1;
    for(int i=1;i<=n+2;i++) {
        fa[i]=i-1;
        ch[i][1]=i+1;
    }
    ch[n+2][1]=0;
    for(int i=n+2;i>=1;i--) {
        pushup(i);
    }
    for(int i=1;i<=n;i++)
    {
        int po=getmnpos(i+1,n+1);
        splay(po,0);
        printf("%d",size[ch[po][0]]);
        reverse(i+1,size[ch[po][0]]+1);
        if(i!=n)printf(" ");
    }
    return 0;
}

优质内容筛选与推荐>>
1、86.构造与类型转换
2、ubuntu下gvim配置文件.vimrc
3、常用操作代码
4、css3 之media type与media query
5、vue+element Table切换页码时被选中状态不变


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn