zoukankan      html  css  js  c++  java
  • 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("
    ");
        }
        return 0;
    }
  • 相关阅读:
    项目发展规划 题解
    善意的投票&小M的作物 题解
    方格取数加强版 题解
    BZOJ1001 狼抓兔子 题解
    a
    一个搬运
    代码“小白”的温故而知新(一)-----OA管理系统
    工作流-----WorkFlow
    温习SQL语句
    浅谈MVC基础
  • 原文地址:https://www.cnblogs.com/zhangleo/p/11122834.html
Copyright © 2011-2022 走看看