题目1544:数字序列区间最小值

http://ac.jobdu.com/problem.php?pid=1544

(1)RMQ算法

题目1544:数字序列区间最小值
#include<stdio.h>

 

int A[100099],d[100099][20];

int n,m;

 

int min(int a,int b){

    return a<=b?a:b;

}

 

void RMQ_init(){

    int i,j;

    for(i=1;i<=n;i++)d[i][0]=A[i];

    for(j=1;(1<<j)<=n;j++){

        for(i=1;i+(1<<j)-1<=n;i++){

            d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]);

        }

    }

}

 

int RMQ_find(int ll,int rr){

    int k=0;

    while((1<<(k+1))<=(rr-ll+1))k++;

    return min(d[ll][k],d[rr-(1<<k)+1][k]);

}

 

int main(){

    while(scanf("%d",&n)!=EOF){

        int i,j;

        for(i=1;i<=n;i++){

            scanf("%d",&A[i]);

        }RMQ_init();

        scanf("%d",&m);

        int ll,rr;

        while(m--){

            scanf("%d%d",&ll,&rr);

            printf("%d\n",RMQ_find(ll,rr));

        }

    }

 

    return 0;

}
View Code

(2)开个格外的数组B, B[i]表示i ~b[i] 内第i个数字最小

题目1544:数字序列区间最小值
#include<stdio.h>

 

int A[100099];

int B[100099];

 

int main(){

    int n,m;

    while(scanf("%d",&n)!=EOF){

        int i,j;

        for(i=1;i<=n;i++){

            scanf("%d",&A[i]);

        }

        for(i=1;i<=n;i++){

            for(j=i+1;j<=n&&A[i]<=A[j];j++);

            B[i]=j-1;

        }

        scanf("%d",&m);

        int ll,rr;

        while(m--){

            scanf("%d%d",&ll,&rr);

            while(B[ll]<rr){

                ll=B[ll]+1;

            }

            printf("%d\n",A[ll]);

        }

    }

 

    return 0;

}
View Code

(3)线段树

你可能感兴趣的:(序列)