zoukankan      html  css  js  c++  java
  • BZOJ_1552_[Cerc2007]robotic sort_splay

    BZOJ_1552_[Cerc2007]robotic sort_splay

    题意:

    分析:

    splay维护区间操作

    可以先把编号排序,给每个编号分配一个固定的点,映射过去

    查找编号的排名时先找到这个点,找出到根的路径

    从上至下pushdown标记,顺便求出这个点的排名

    然后翻转啥的就好做了

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 100050
    #define ls ch[p][0]
    #define rs ch[p][1]
    #define get(x) (ch[f[x]][1]==x)
    int a[N],ch[N][2],f[N],siz[N],val[N],turn[N],rt;
    int n,w[N];
    struct A{
        int num,id;
    }b[N];
    bool cmp(const A &x,const A &y)
    {
        if(x.num==y.num)return x.id<y.id;
        return x.num<y.num;
    }
    void print(int p)
    {
        if(!p)return ;
        if(ls)print(ls);
        printf("p=%d ,val[p]=%d ",p,val[p]);
        if(rs)print(rs);
    }
    void pushup(int p){ if(p) siz[p]=siz[ls]+siz[rs]+1; }
    void pushdown(int p)
    {
        if(turn[p])
        {
            turn[p]=0;
            turn[ls]^=1;turn[rs]^=1;
            swap(ch[ls][0],ch[ls][1]);
            swap(ch[rs][0],ch[rs][1]);
        }
    }
    void rotate(int x)
    {
        int y=f[x],z=f[y],k=get(x);
        ch[y][k]=ch[x][k^1];f[ch[y][k]]=y;ch[x][k^1]=y;
        f[y]=x;f[x]=z;if(z)ch[z][ch[z][1]==y]=x;
        pushup(y),pushup(x);if(rt==y)rt=x;
    }
    void splay(int x,int y)
    {
        for(int fa;(fa=f[x])!=y;rotate(x))
            if(f[fa]!=y)
                rotate((get(x)==get(fa)) ? fa : x);
    }
    int find(int x)
    {
        int p=rt;
        while(1){
            pushdown(p);
            if(x<=siz[ls])p=ls;
            else{
                x-=siz[ls]+1;
                if(!x)return p;
                p=rs;
            }
        }
    }
    void build(int fa,int l,int r,int flg)
    {
        if(l>r)return ;
        int mid=l+r>>1;
        ch[fa][flg]=mid;
        f[mid]=fa;
        siz[mid]=1;
        val[mid]=a[mid-1];
        w[a[mid-1]]=mid;
        build(mid,l,mid-1,0);
        build(mid,mid+1,r,1);
        pushup(mid);
    }
    int getrank(int p)
    {
        int cnt=0;
        while(p)
        {
            a[++cnt]=p;
            p=f[p];
        }
        int i;
        for(i=cnt;i;i--) pushdown(a[i]);
        splay(a[1],0);
        return siz[ch[a[1]][0]];
    }
    void reverse(int x,int p)
    {
        x=find(x);
        p=find(p);
        splay(x,0);
        splay(p,rt);
        turn[ls]=1;
        swap(ch[ls][0],ch[ls][1]);
        pushup(p);pushup(x);
    }
    int main()
    {
        scanf("%d",&n);
        int i;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&b[i].num);
            b[i].id=i;
        }
        sort(b+1,b+n+1,cmp);
        for(i=1;i<=n;i++)
        {
            a[b[i].id]=i;
        }
        build(0,1,n+2,1);
        rt=n+3>>1;
        for(i=1;i<=n;i++)
        {
            int tmp=getrank(w[i]);
            if(i-1)printf(" %d",tmp);
            else printf("%d",tmp);
            reverse(i,tmp+2);
        }
    }
    
  • 相关阅读:
    MySql 范式
    MySql 多表关系
    MySql 约束条件
    MySql 枚举和集合 详解
    【RoR win32】新建rails项目找不到script/server的解决办法
    【RoR win32】安装RoR
    【RoR win32】提高rails new时bundle install运行速度
    【bs4】安装beautifulsoup
    【py分析网页】可能有用的-re去除网页上的杂碎
    【pyQuery】抓取startup news首页
  • 原文地址:https://www.cnblogs.com/suika/p/8592982.html
Copyright © 2011-2022 走看看