置换,模拟,优化(HDU 5338,ZZX and Permutations)

来源:互联网 发布:淘宝能改店铺名称吗 编辑:程序博客网 时间:2024/05/17 23:55

理解置换的概念以及题意后,剩下的就是模拟了。


花了挺长时间,主要是模拟有漏洞+想暴力过。

希望自己能养成一个做题目的好习惯,虽然写完代码再来debug能比较稳定地查出错误,但是一旦出现了整体性的解法错误就得推倒重来,这会花掉非常多的时间,希望自己能权衡一下写代码和想明白之间的时间分配,任何基本功都是值得坚持训练的。


代码

#include<stdio.h>#include<algorithm>#define m ((l+r)>>1)#define ls (now<<1)#define rs (ls|1)using namespace std;const int maxn = 100010;int n;int a[maxn];int p[maxn];int bar[maxn];int nex[maxn];int MAXBAR;int tree1[maxn<<2][2];int tree2[maxn<<2];void maintain2(int now){    tree2[now]=max(tree2[ls],tree2[rs]);}void build(int l,int r,int now){    tree1[now][0]=tree1[now][1]=0;    if(l==r)    {        tree2[now]=a[l];        return;    }    build(l,m,ls);    build(m+1,r,rs);    maintain2(now);}void pushdown1(int now){    tree1[ls][1]=max(tree1[ls][1],tree1[now][1]);    tree1[rs][1]=max(tree1[rs][1],tree1[now][1]);    tree1[ls][0]=max(tree1[ls][0],tree1[ls][1]);    tree1[rs][0]=max(tree1[rs][0],tree1[rs][1]);}void update1(int l,int r,int now,int ql,int qr,int val){    if(l>qr||r<ql) return;    if(ql<=l&&r<=qr)    {        tree1[now][0]=max(tree1[now][0],val);        tree1[now][1]=max(tree1[now][1],val);        return;    }    pushdown1(now);    update1(l,m,ls,ql,qr,val);    update1(m+1,r,rs,ql,qr,val);}int qry1(int l,int r,int now,int pos){    if(l==r) return tree1[now][0];    pushdown1(now);    if(pos<=m) return qry1(l,m,ls,pos);    else return qry1(m+1,r,rs,pos);}void update2(int l,int r,int now,int pos){    if(l==r)    {        tree2[now]=0;        return;    }    if(pos<=m) update2(l,m,ls,pos);    else update2(m+1,r,rs,pos);    maintain2(now);}int qry2(int l,int r,int now,int ql,int qr){    if(l>qr||r<ql) return 0;    if(ql<=l&&r<=qr) return tree2[now];    return max(qry2(l,m,ls,ql,qr),qry2(m+1,r,rs,ql,qr));}void init(){    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d",a+i);        p[a[i]]=i;        bar[i]=0;        nex[i]=0;    }    MAXBAR=0;    build(1,n,1);}int GETMAX(int pos){    int L = qry1(1,n,1,pos);    return qry2(1,n,1,L+1,pos);}void add(int L,int R){    for(int i=0;i<R-L+1;i++)    {        int j = (i+1)%(R-L+1);        bar[L+i]=-1;        nex[a[i+L]]=a[j+L];    }    MAXBAR=max(MAXBAR,R);    update1(1,n,1,R+1,n,R);    bar[R]=1;    bar[L-1]=1;}void print(){    for(int i=1;i<=n;i++) printf("%d%c",nex[i],i==n?'\n':' ');}void solve(){    init();    for(int i=1;i<=n;i++) if(!nex[i])    {        a[n+1]=a[MAXBAR+1];        int PMAX = GETMAX(p[i]);        int NMAX = bar[p[i]]==1?0:a[p[i]+1];        if(PMAX>=NMAX) add(p[PMAX],p[i]);        else        {            update2(1,n,1,p[i]+1);            bar[p[i]]=-1;            nex[i]=a[p[i]+1];        }    }    print();}int main(){    int T;    scanf("%d",&T);    while(T--) solve();    return 0;}


阅读全文
0 0