Hdu 5338 ZZX and Permutations(线段树+贪心)

来源:互联网 发布:澳门网络彩票 编辑:程序博客网 时间:2024/05/22 03:52

解析:

首先用set维护被Cirlcle Notation切开的不连续的各个段。

然后从i开始,(p[i]为i的位置)

找到其在set中的左右端点,左边的最大值为value_l,右边p[i]+1的值为value_r。

若value_l>value_r,则{p[value_l],p[value_l]+1,...,p[i] }为一个CircleNotation,并再用set维护剩下的段。

若value_l<value_r,则 i 对应的是value_r,在线段树中将p[i]+1置为0.


[code]:

#include<cstdio>#include<cstring>#include<algorithm>#include<set>#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;const int maxn = 1e5+5;int n,a[maxn],pos[maxn],ans[maxn],C[maxn<<2];set<int> ms;set<int>::iterator it;void push_up(int rt){    C[rt] = max(C[rt<<1],C[rt<<1|1]);}void build(int l,int r,int rt){    if(l == r){        C[rt] = a[l];        return;    }    int mid = (l+r)>>1;    build(lson);build(rson);    push_up(rt);}void update(int k,int x,int l,int r,int rt){    if(l == r){        C[rt] = x;        return;    }    int mid = (l+r)>>1;    if(k <= mid) update(k,x,lson);    else update(k,x,rson);    push_up(rt);}int query(int a,int b,int l,int r,int rt){    if(a <= l&&r <= b) return C[rt];    if(l > b||r < a) return -1;    int mid = (l+r)>>1;    return max(query(a,b,lson),query(a,b,rson));}void init(){    memset(ans,-1,(n+1)*sizeof(int));    ms.clear();    ms.insert(0);    ms.insert(n);}void sol(){    int i,j,lb,rb,cur,value_l,value_r;    for(i = 1;i <= n;i++){        if(ans[i] != -1) continue;        it = ms.lower_bound(pos[i]);        rb = *it;--it;lb = *it;lb++;        cur = pos[i];        value_r = cur==rb?-1:a[cur+1];        value_l = query(lb,cur,1,n,1);//printf("%d %d %d\n",i,value_l,value_r);        if(value_l>value_r){            ms.insert(pos[value_l]-1);            ms.insert(cur);            ans[i] = value_l;            for(j = pos[value_l];j < cur;j++){                ans[a[j]] = a[j+1];            }        }else{            ans[i] = value_r;            update(cur+1,-1,1,n,1);        }    }    for(i = 1;i <= n;i++){        if(i-1) putchar(' ');        printf("%d",ans[i]);    }    putchar('\n');}int main(){    int i,j,cas,l,r;    scanf("%d",&cas);    while(cas--){        scanf("%d",&n);        init();        for(i = 1;i <= n;i++){            scanf("%d",&a[i]);            pos[a[i]] = i;        }        build(1,n,1);        sol();    }    return 0;}



0 0
原创粉丝点击