RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=3603

#include<stdio.h>
#include<string.h>
#include<math.h>
#define N 300001
int n;
int vis[N];
int pre[N];
int dp[N][19];
void swap(int *a,int *b){
    *a+=*b;
    *b=*a-*b;
    *a-=*b;
}
int b_search(int x,int y){
    int m;
    int k=0;
    int v=x;
    while(x<y){
        m=(x+y)>>1;

        if(pre[m]<v){
            k=m;
            x=m+1;
        }
        else y=m;
    }
    return k;
}
int ask_RMQ(int a,int b){
    int k;
    if(a>b) return 0;
    k=(int)(log(b-a+1)/log(2));
    return max(dp[a][k],dp[b-(1<<k)+1][k]);
}
int max(int a,int b){
    return a>b?a:b;
}
int get_ans(int a,int b){
    int k=b_search(a,b+1);
    if(k) return max(k-a+1,ask_RMQ(k+1,b));
    else return ask_RMQ(a,b);
}
void init_RMQ(){
    int i,j;
    for(i=1;i<=n;++i) dp[i][0]=i-pre[i];
    for(j=1;(1<<j)<=n;++j){
        for(i=1;i<n;++i){
            dp[i][j]=dp[i][j-1];
            if(i+(1<<(j-1))<n&&dp[i][j]>dp[i+(1<<(j-1))][j-1]) dp[i][j]=dp[i+(1<<(j-1))][j-1];
        }
    }
}
int main(){
    while(~scanf("%d",&n)){
        int i,m,x,a,b;
        memset(vis,-1,sizeof(vis));
        for(i=1;i<=n;++i){
            scanf("%d",&x);
            if(vis[x]!=-1) pre[i]=vis[x];
            else pre[i]=0;
            if(pre[i]<pre[i-1]) pre[i]=pre[i-1];
            vis[x]=i;
        }
        init_RMQ();
        scanf("%d",&m);
        for(i=0;i<m;++i){
            scanf("%d%d",&a,&b);
            if(a^b){
                if(a>b) swap(&a,&b);
                printf("%d\n",get_ans(a,b));
            }
            else printf("1\n");
        }
    }
    return 0;
}
View Code

 

 

posted @ 2013-11-14 15:50  清风旋叶  阅读(187)  评论(0)    收藏  举报