UVA11235 Frequent values

思路

连续的值只会分布在一起成一个块

讨论两边的块,中间就是RMQ了

ST表即可

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int times[100100],belong[100100],lb[100100],rb[100100],inq,n,q,st[100100][21];
void init_ST(void){
    for(int i=1;i<=inq;i++)
        st[i][0]=times[i];
    for(int i=1;i<21;i++)
        for(int j=1;j<=n;j++)
            st[j][i]=max(st[j][i-1],st[min(j+(1<<(i-1)),n+10)][i-1]);
}
int query(int l,int r){
    if(l>r)
        return 0;
    int k=0;
    while((1<<(k+1))<=(r-l+1)){
        k++;
    }
    return max(st[l][k],st[r-(1<<k)+1][k]);
}
int main(){
    freopen("test.in","r",stdin);
    freopen("test.out","w",stdout);
    scanf("%d",&n);
    while(n){
        scanf("%d",&q);
        memset(times,0,sizeof(times));
        memset(belong,0,sizeof(belong));
        memset(st,0,sizeof(st));
        inq=0;
        int last=0x3f3f3f3f;
        for(int i=1;i<=n;i++){
            int x;
            scanf("%d",&x);
            if(x!=last){
                last=x;
                ++inq;
                times[inq]=1;
                lb[inq]=i;
            }
            else
                times[inq]++;
            belong[i]=inq;
            rb[inq]=i;
        }
        init_ST();
        for(int i=1;i<=q;i++){
            int l,r,lx,rx;
            scanf("%d %d",&l,&r);
            lx=belong[l];
            rx=belong[r];
            int lt=min(rb[lx],r)-max(lb[lx],l)+1,rt=min(rb[rx],r)-max(lb[rx],l)+1;
            printf("%d\n",max(max(query(lx+1,rx-1),lt),rt));    
        }
        scanf("%d",&n);
    }
    return 0;
}
posted @ 2019-04-10 19:23  dreagonm  阅读(121)  评论(0编辑  收藏  举报