UVa11235 sparse-table RLE

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=23846

游程编码(RunLength Encoding) RLE, Spares-Table

 动态询问数组中出现最多的值的出现次数



/*************************************************************************
	> File Name: UVa11235.cpp
	> Author:HaoWei 
	> Mail:liang199611@outlook.com 
	> Created Time: 2016年06月29日 星期三 15时24分53秒
 ************************************************************************/

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;
const int maxn=111111;
#define rep(i,n) for(int i=0;i<n;i++)
int a[maxn],n,cnt,q;
int kount[maxn],id[maxn],ll[maxn],rr[maxn];
int d[maxn][22];
void RMQ_init(int n)
{
    rep(i,n) d[i][0]=kount[i];
    for(int j=1;(1<<j)<=n;j++)
        for(int i=0;i+(1<<j)-1<n;i++)
            d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
}

int RMQ(int L,int R)
{
    int k=0;
    while((1<<(k+1))<=R-L+1) k++;
    return max(d[L][k],d[R-(1<<k)+1][k]);
}
int main()
{
    while(scanf("%d%d",&n,&q)==2)
    {
        if(!n) break;
        rep(i,n) scanf("%d",&a[i]);
        memset(ll,-1,sizeof(ll));memset(rr,-1,sizeof(rr));
        cnt=0;
        rep(i,n){
            if(i==0) kount[cnt]=1,ll[i]=0;
            else if(a[i]!=a[i-1]) kount[++cnt]=1,rr[i-1]=i-1,ll[i]=i;
            else kount[cnt]++;
            id[i]=cnt;
        }
        rr[n-1]=n-1;cnt++;
        for(int i=0;i<n;i++) if(i!=0&&ll[i]==-1) ll[i]=ll[i-1];
        for(int i=n-1;i>=0;i--) if(i!=(n-1)&&rr[i]==-1) rr[i]=rr[i+1];
        RMQ_init(cnt);

  /*      rep(i,n) printf(" id:%d ll:%d rr:%d",id[i],ll[i],rr[i]);
        cout<<endl;
        rep(i,cnt) printf("count:%d ",kount[i]);*/
        rep(tt,q)
        {
            int L,R,l,r,res;
            scanf("%d%d",&L,&R);L--,R--;
           // printf("\nrr[L]:%d,L:%d,R:%d,ll[R]:%d\n",rr[L],L,R,ll[R]);
            //L=id[L];R=id[R];
            l=id[L]+1;r=id[R]-1;
            if(id[L]==id[R]) {printf("%d\n",R-L+1);continue;}
            res=max(rr[L]-L+1,R-ll[R]+1);
         //  printf("\nleft:%d right:%d\n",l,r);
            if(r>=l) res=max(res,RMQ(l,r));
            printf("%d\n",res);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值