zoukankan      html  css  js  c++  java
  • BZOJ1552: [Cerc2007]robotic sort & BZOJ3506: [Cqoi2014]排序机械臂

    【传送门:BZOJ1552&BZOJ3506


    简要题意:

      给出一个长度为n的序列,现在要将它们进行排序,排序的操作为:

      如果当前是第i次排序,则先找到当前序列中的最i小值所在位置x(如果有多个,则找到一开始给出序列顺序中排在最前面的数),然后将第i到第x的位置上的数都翻转

      求出每次操作中x的值


    题解:

      splay裸题,树上记录最小值以及如果有多个最小值时初始位置最小的数在树上的位置,以及翻转标记

      然后每做完一次操作,就要把x从树中删掉就行了


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #define Maxn 110000
    #define INF 1<<30
    using namespace std;
    struct T{int f,son[2],c,d,p,mp,mn;bool fz;T(){mn=INF;fz=false;}}tr[Maxn];int len;
    int rt,a[Maxn];
    void update(int x)
    {
        int lc=tr[x].son[0],rc=tr[x].son[1];
        int mmin=min(tr[x].d,min(tr[lc].mn,tr[rc].mn)),t=INF;
        if(tr[x].d==mmin) if(t>tr[x].p) t=tr[x].p;
        if(tr[lc].mn==mmin) if(t>tr[lc].mp) t=tr[lc].mp;
        if(tr[rc].mn==mmin) if(t>tr[rc].mp) t=tr[rc].mp;
        tr[x].mn=mmin;tr[x].mp=t;
        tr[x].c=tr[lc].c+tr[rc].c+(tr[x].d!=INF);
    }
    int ins(int l,int r)
    {
        int mid=(l+r)/2;
        int now=++len;
        tr[now].d=a[mid];tr[now].p=mid;
        if(l<mid) tr[now].son[0]=ins(l,mid-1),tr[tr[now].son[0]].f=now;
        if(mid<r) tr[now].son[1]=ins(mid+1,r),tr[tr[now].son[1]].f=now;
        update(now);
        return now;
    }
    void reverse(int x)
    {
        int lc=tr[x].son[0],rc=tr[x].son[1];
        if(lc!=0) tr[lc].fz^=1;
        if(rc!=0) tr[rc].fz^=1;
        swap(tr[x].son[0],tr[x].son[1]);
        tr[x].fz^=1;
    }
    void rotate(int x,int w)
    {
        int f=tr[x].f,ff=tr[f].f;
        int r,R;
        r=tr[x].son[w];R=f;
        tr[R].son[1-w]=r;
        if(r!=0) tr[r].f=R;
        r=x;R=ff;
        if(tr[R].son[0]==f) tr[R].son[0]=r;
        else tr[R].son[1]=r;
        tr[r].f=R;
        r=f;R=x;
        tr[R].son[w]=r;
        tr[r].f=R;
        update(f);
        update(x);
    }
    int s[Maxn],tot;
    void splay(int x,int tp)
    {
        int i=x,tot=0;
        while(tr[i].f!=tp)
        {
            s[++tot]=i;
            i=tr[i].f;
        }
        s[++tot]=i;
        while(tot!=0)
        {
            i=s[tot--];
            if(tr[i].fz==true) reverse(i);
        }
        while(tr[x].f!=tp)
        {
            int f=tr[x].f,ff=tr[f].f;
            if(ff==tp)
            {
                if(tr[f].son[0]==x) rotate(x,1);
                else rotate(x,0);
            }
            else
            {
                if(tr[f].son[0]==x&&tr[ff].son[0]==f){rotate(f,1);rotate(x,1);continue;}
                if(tr[f].son[0]==x&&tr[ff].son[1]==f){rotate(x,1);rotate(x,0);continue;}
                if(tr[f].son[1]==x&&tr[ff].son[0]==f){rotate(x,0);rotate(x,1);continue;}
                if(tr[f].son[1]==x&&tr[ff].son[1]==f){rotate(f,0);rotate(x,0);continue;}
            }
        }
        if(tp==0) rt=x;
    }
    void del(int x)
    {
        splay(x,0);
        if(tr[x].son[0]==0&&tr[x].son[1]==0) rt=0;
        else if(tr[x].son[0]==0&&tr[x].son[1]!=0) rt=tr[x].son[1],tr[rt].f=0;
        else if(tr[x].son[0]!=0&&tr[x].son[1]==0) rt=tr[x].son[0],tr[rt].fz^=1,tr[rt].f=0;
        else
        {
            if(tr[x].fz==true) reverse(x);
            int p=tr[x].son[1];
            if(tr[p].fz==true) reverse(p);
            while(tr[p].son[0]!=0)
            {
                p=tr[p].son[0];
                if(tr[p].fz==true) reverse(p);
            }
            splay(p,x);
            int r=tr[x].son[0],R=p;
            tr[R].son[0]=r;
            tr[r].f=R;
            rt=R;tr[R].f=0;
            update(R);
            tr[r].fz^=1;
        }
        len--;
    }
    int getmin()
    {
        int x=rt;
        while(tr[x].son[0]!=0||tr[x].son[1]!=0)
        {
            if(tr[x].fz==true) reverse(x);
            int lc=tr[x].son[0],rc=tr[x].son[1];
            int mmin=min(tr[x].d,min(tr[lc].mn,tr[rc].mn)),t=INF;
            if(tr[x].d==mmin) if(t>tr[x].p) t=tr[x].p;
            if(tr[lc].mn==mmin) if(t>tr[lc].mp) t=tr[lc].mp,x=lc;
            if(tr[rc].mn==mmin) if(t>tr[rc].mp) t=tr[rc].mp,x=rc;
            if(x!=lc&&x!=rc) break;
        }
        return x;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=2;i<=n+1;i++) scanf("%d",&a[i]);a[1]=a[n+2]=INF;
        len=0;rt=ins(1,n+2);
        for(int i=1;i<=n;i++)
        {
            int x=getmin();
            splay(x,0);
            if(i<n) printf("%d ",tr[tr[x].son[0]].c+i);
            else printf("%d
    ",tr[tr[x].son[0]].c+i);
            del(x);
        }
        return 0;
    }

     

  • 相关阅读:
    CSRF的防御解决过程
    Spring生态研习【三】:Spring-kafka
    Spring生态研习【二】:SpEL(Spring Expression Language)
    Spring生态研习【一】:定时任务Spring-task
    给定一个大的任务,需要在考虑性能的情况下,快速处理完,并报告结果
    给定一个大于2的偶数,将其分解为两个质数的和
    一个求解平方根的算法题
    Kafka研究【一】:bring up环境
    LB+nginx+tomcat7集群模式下的https请求重定向(redirect)后变成http的解决方案
    IDEA使用笔记(八)——自动生成 serialVersionUID 的设置
  • 原文地址:https://www.cnblogs.com/Never-mind/p/10154125.html
Copyright © 2011-2022 走看看