HDU 5338 ZZX and Permutations 线段树

来源:互联网 发布:ahc官网扫码软件 编辑:程序博客网 时间:2024/06/11 21:10

题目链接:HDU 5338
题意:给一个去掉括号的置换半成品,问如何加括号可以使原序列字典序最大。
思路:
思路很明确

  • 1、肯定是贪心的考虑使靠前位置的尽量大。
  • 2、那么就找从当前位置到之前的右括号之间最大的值与后继进行比较。
  • 括号直接用SET维护就可以了,最大值用线段树维护。比赛的时候SB用线段树维护的右括号位置,幸亏范围小。

代码:

#include <cstdio>#include <cstring>#include <queue>#include <iostream>#include <algorithm>#define Lson o<<1,l,mid#define Rson o<<1|1,mid+1,r#define MID int mid = (l+r)>>1using namespace std;const int maxn=100100;int data[maxn],fd[maxn];//namespace SGM1{//    set<int> st;//    int init(int n){//        st.clear();//        st.insert(0);//    }//    int get(int pos){//        return 0-*st.lower_bound(-pos);//    }//    int update(int pos){//        st.insert(-pos);//    }//}namespace SGM1{    int maxv[maxn*4];    int maxe=-1,n;    void init(int _n){        n=_n;        for(int i=0;i<4*maxn;i++){            maxv[i]=0;        }    }    void modify(int o,int l,int r,int pos){        if(l==r){            maxv[o]=pos;            return ;        }        MID;        if(pos<=mid)modify(Lson,pos);        else  modify(Rson,pos);        maxv[o]=max(maxv[o<<1],maxv[o<<1|1]);    }    void quarry(int o,int l,int r,int L,int R){        if(L<=l&&r<=R){            maxe=max(maxe,maxv[o]);            return ;        }        MID;        if(L<=mid)quarry(Lson,L,R);        if(R>mid )quarry(Rson,L,R);    }    int get(int pos){        maxe=-1;        quarry(1,1,n,1,pos);        return maxe;    }    int update(int pos){        modify(1,1,n,pos);    }}namespace SGM2{    int maxv[maxn*4];    int maxe,n;    int a[maxn];    int maxa(int x,int y){        if(a[x]>a[y]) return x;        return y;    }    void build(int o,int l,int r){        if(l==r){            maxv[o]=l;            return ;        }        MID;        build(Lson);        build(Rson);        maxv[o]=maxa(maxv[o<<1],maxv[o<<1|1]);    }    void init(int _n){        n=_n;        a[0]=0;        for(int i=1;i<=n;i++)a[i]=data[i];        build(1,1,n);    }    void modify(int o,int l,int r,int pos){        if(l==r){            maxv[o]=l;            return ;        }        MID;        if(pos<=mid)modify(Lson,pos);        else  modify(Rson,pos);        maxv[o]=maxa(maxv[o<<1],maxv[o<<1|1]);    }    void quarry(int o,int l,int r,int L,int R){        if(L<=l&&r<=R){            maxe=maxa(maxe,maxv[o]);            return ;        }        MID;        if(L<=mid)quarry(Lson,L,R);        if(R>mid )quarry(Rson,L,R);    }    int get(int L,int R){        maxe=0;        quarry(1,1,n,L,R);        return maxe;    }    void update(int pos){        a[pos]=0;        modify(1,1,n,pos);    }}int ans[maxn];int main(){    int n,T;   // freopen("data.txt","r",stdin);    scanf("%d",&T);    while(T--){        memset(ans,0,sizeof(ans));        scanf("%d",&n);        for(int i=1;i<=n;i++){            scanf("%d",&data[i]);            fd[data[i]]=i;        }        SGM1::init(n);        SGM2::init(n);        for(int i=1;i<=n;i++){            if(!ans[i]){                int tpos=SGM1::get(fd[i])+1;                tpos=SGM2::get(tpos,fd[i]);                if(data[tpos]>data[fd[i]+1]||SGM1::get(fd[i]+1)>=fd[i]+1||fd[i]==n){                    SGM1::update(tpos);                    SGM1::update(fd[i]);                    for(int j=tpos;j<fd[i];j++){                        ans[data[j]]=data[j+1];                    }                    ans[i]=data[tpos];                }                else{                    SGM2::update(fd[i]+1);                    ans[i]=data[fd[i]+1];                }            }        }        for(int i=1;i<=n;i++){            if(i>1)putchar(' ');            printf("%d",ans[i]);        }        puts("");    }    return 0;}
0 0