【题意】
由于HZF长得太帅,被各种人调戏是绝对的啦!今天上决十分的无聊,于是就去欺负HZF不会数据结构,嘻嘻。来点简单的嘛,免得峰哥报复,那就……HZF嘿嘿一笑:看我无敌版函数式平衡逆天启发式线段树!
Input
多组。 第一排两个个正整N,M;N <= 500,000。M <= 1000,000。 接下来N个整数Ai(-500,000 <= Ai <= 500,000),为一个不降序列。 接下来的M排,代表M次询问,每排一个L,R,保证1 <= L <= R <= N。
Output
对于每一次询问,输入该区间内出现次数最多的数出现的次数。
10 1 1 1 2 2 2 3 3 3 3 5 1 10
4
【解题方法】RMQ即可。
【AC 代码】
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 500010;
int a[maxn],l[maxn],r[maxn];
struct ST{
int n,dp[maxn][24];
void init(int _n)
{
n = _n;
for(int i=1; i<=n; i++) dp[i][0] = l[i];
}
void update()
{
for(int j=1; (1<<j)<=n; j++)
{
for(int i=1; i+(1<<j)-1<=n; i++){
dp[i][j] = max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
}
int queryans(int L,int R)
{
if(L>R) return 0;
int k = 0;
while(1<<(k+1)<=R-L+1) k++;
return max(dp[L][k],dp[R-(1<<k)+1][k]);
}
}st;
int main()
{
int n,q,L,R,ans;
while(scanf("%d%d",&n,&q)!=EOF)
{
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
l[1] = 1;
for(int i=2; i<=n; i++){
if(a[i]==a[i-1]) l[i] = l[i-1]+1;
else l[i] = 1;
}
r[n] = 1;
for(int i=n-1; i>=1; i--)
{
if(a[i]==a[i+1]) r[i] = r[i+1]+1;
else r[i]=1;
}
st.init(n);
st.update();
while(q--)
{
scanf("%d%d",&L,&R);
if(r[L]>=R-L+1) ans=R-L+1;
else ans = max(r[L],st.queryans(L+r[L],R));
printf("%d\n",ans);
}
}
return 0;
}