hdu 5338

因为起名无能,所以数组意义弄混了,一直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 100010

struct 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;
}


posted @ 2015-08-07 16:50  buzhidaohahaha  阅读(88)  评论(0编辑  收藏  举报