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