hdu 5338

来源:互联网 发布:广安门中医院挂号软件 编辑:程序博客网 时间:2024/06/16 03:41

因为起名无能,所以数组意义弄混了,一直wr,终于过了,结论就是好好学英语,养成自己起名的一贯习惯。这道题的重点在于怎么找有效区间内最大的值,通过看别的代码(http://blog.csdn.net/winddreams/article/details/47156293),才发现原来可以这样写。好多天了,终于把这道题过了,披着组合数学外衣的线段树!!!!!!敲打

(今天中午吃的砂锅麻花,再一次感叹,学校的砂锅,即使夏天吃,也很好吃,想吃木桶豆腐和羊肉泡馍。)

2015.8.29:

对于数的大小比较和字典序的大小比较似乎都会有一个贪心的过程。

(如果有人在说,学数学有什么意义的话,我就可以正大光明的告诉它,可以在csdn的博客里写文章,每次的验证码都让我感觉回到了小学,每天30道计算题偷笑

#include<stdio.h>#include<string.h>#include<iostream>using namespace std;#define N 100010struct node{    int maxnum;    int maxb;};struct node array[4*N];int num[N];int loca[N];int ans[N];int sign[N];int a,b;int max(int a,int b){    return a>b?a:b;}void update(int root){    array[root].maxnum=max(array[root<<1].maxnum,array[(root<<1)+1].maxnum);    array[root].maxb=max(array[root<<1].maxb,array[(root<<1)+1].maxb);    return;}void build(int root,int l,int r){    if(l==r){        scanf("%d",&num[l]);        array[root].maxnum=num[l];        array[root].maxb=0;        loca[num[l]]=l;        return;    }    else{        int middle=(l+r)>>1;        build(root<<1,l,middle);        build((root<<1)+1,middle+1,r);        update(root);        return;    }}int queryb(int root,int l,int r){    //printf("%d %dha %d %dhei ",l,r,a,b);    if(a>b){        return -1;    }    else{        if(a<=l&&b>=r){            return array[root].maxb;        }        else{            int middle=(l+r)>>1;            if(b<=middle){                return queryb(root<<1,l,middle);            }            else if(a>middle){                return queryb((root<<1)+1,middle+1,r);            }            else{                return  max(queryb(root<<1,l,middle),queryb((root<<1)+1,middle+1,r));            }        }    }}int querynum(int root,int l,int r){    if(l==r){        return array[root].maxnum;    }    else{        int middle=(l+r)>>1;        if(a<=l&&b>=r){            return array[root].maxnum;        }        else{            if(b<=middle){                return querynum(root<<1,l,middle);            }            else if(a>middle){                return querynum((root<<1)+1,middle+1,r);            }            else{                return max(querynum(root<<1,l,middle),querynum((root<<1)+1,middle+1,r));            }        }    }}void updateb(int root,int l,int r){    if(l==r){        array[root].maxb=l;        return;    }    else{        int middle=(l+r)>>1;        if(a<=middle){            updateb(root<<1,l,middle);        }        else{            updateb((root<<1)+1,middle+1,r);        }        update(root);        return;    }}void updatenum(int root,int l,int r){    if(l==r){        array[root].maxnum=-1;        return;    }    else{        int middle=(l+r)>>1;        if(a<=middle){            updatenum(root<<1,l,middle);        }        else{            updatenum((root<<1)+1,middle+1,r);        }        update(root);        return;    }}int main(){    int t;    int n;    scanf("%d",&t);    while(t--){        scanf("%d",&n);        if(n==0){            continue;        }        memset(array,0,sizeof(array));        build(1,1,n);        memset(ans,-1,sizeof(ans));        memset(sign,0,sizeof(sign));        for(int i=1;i<=n;i++){            if(ans[i]!=-1){                continue;            }            else{                int k1,k2,k3;                a=1;                b=loca[i]-1;                int templ=queryb(1,1,n);//printf("wo shi da hao ren");                templ++;                if(templ==0||templ==loca[i]){                    k1=-1;                }                else{                    a=templ;                    b=loca[i]-1;                    k1=querynum(1,1,n);                }//k1的值已验证正确                if((loca[i]-1>=1)&&ans[num[loca[i]-1]]==i){                    k2=-1;                }                else{                    k2=i;                }                /*if(i==4){                    printf("%d %d\n",ans[loca[i]+1],ans[5]);                }*/                if((loca[i]+1<=n)&&(ans[num[loca[i]+1]]==-1)){                    k3=num[loca[i]+1];                }                else if((loca[i]+1<=n)&&num[loca[i]+1]<i&&ans[num[loca[i]+1]]!=num[loca[i]+1]&&sign[num[loca[i]+1]]==0){                    k3=num[loca[i]+1];                }                else{                    k3=-1;                }                if(k1>k2&&k1>k3){                    sign[k1]=1;                    for(int j=loca[k1];j<loca[i];j++){                        ans[num[j]]=num[j+1];                    }                    ans[i]=k1;                    a=loca[i];                    updateb(1,1,n);                }                else if(k2>k1&&k2>k3){                    sign[k2]=1;                    ans[i]=k2;                    a=loca[i];                    updateb(1,1,n);                }                else if(k3>k1&&k3>k2){                    ans[i]=k3;                    a=loca[k3];                    updatenum(1,1,n);                }                //printf("%d %d %d %d\n",i,k1,k2,k3);            }        }        printf("%d",ans[1]);        for(int i=2;i<=n;i++){            printf(" %d",ans[i]);        }        printf("\n");    }    return 0;}


0 0