UVa11235 RMQ

时间:2023-03-09 03:10:00
UVa11235 RMQ

input

1<=n,q<=100000

升序序列a1 a2 a3 ... an -100000<=ai<=100000

q行i j   1<=i,j<=n

输入结束标志n=0

output

对于每行i,j输出区间[i,j]中出现最多的数的个数

RMQ问题,处理的时候要合并区间

 #include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <set> using namespace std; int a[][],b[][],n,q,d[][];//a[i][0]是第i个数,a[i][1]是第i个数在b数组中的下标,b[i][0]是开始的下标,b[1][1]是连续的个数 void RMQ_init()
{
for(int i=;i<n;i++)
d[i][]=;
for(int j=;(<<j)-<n;j++)
for(int i=;i+(<<j)-<n;i++)
{
int i1=i+(<<(j-));
d[i][j]=max(d[i][j-],d[i1][j-]);
if(a[i1-][]==a[i1][])//区间中间合并
{
//printf("i=%d j=%d d=%d\n",i,j,d[i][j]);
int beg,end,idx=a[i1][];
beg=max(b[idx][],i);
end=min(b[idx][]+b[idx][]-,i+(<<j)-);
//printf("beg=%d end=%d\n",beg,end);
d[i][j]=max(d[i][j],end-beg+);
//printf("d=%d\n",d[i][j]);
}
}
} int RMQ(int l,int r)
{
int k=;
while((<<(k+))<=r-l+) k++;
int maxd,beg,end,idx=r-(<<k)+;
maxd=max(d[l][k],d[idx][k]);
//区间合并
beg=max(b[a[idx][]][],l);
end=min(b[a[idx][]][]+b[a[idx][]][]-,r);
//printf("beg=%d end=%d\n",beg,end);
return max(maxd,end-beg+);
} int main()
{
freopen("/home/user/桌面/in","r",stdin);
while(scanf("%d",&n)==&&n)
{
scanf("%d",&q);
memset(b,,sizeof(b));
scanf("%d",&a[][]);
int j=;
a[][]=;
b[][]=;
b[][]=;
for(int i=;i<n;i++)
{
scanf("%d",&a[i][]);
if(a[i][]==a[i-][])
{
b[j][]++;
a[i][]=j;
}
else
{
j++;
b[j][]=i;
b[j][]++;
a[i][]=j;
}
}
//for(int i=0;i<n;i++) printf("%d %d\n",a[i][0],a[i][1]);
//for(int i=0;i<=j;i++) printf("%d %d\n",b[i][0],b[i][1]);
RMQ_init();
for(int i=,l,r;i<q;i++)
{
scanf("%d%d",&l,&r);
printf("%d\n",RMQ(l-,r-));
}
}
return ;
}