POJ 3368
借助这道题,顺便学习了离散化的思想。
写代码是一件需要专注的事情,离散化处理的时候精神不做到高度集中,一道水题不能快速切出,训练需要注意
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <deque>
using namespace std;
const int maxn= 1e5+5;
int a[maxn], b[maxn], L[maxn], R[maxn], hs[maxn];
int mm[maxn], sptb[maxn][20];
void InitRMQ(int n, int b[])
{
mm[0]= -1;
for (int i= 1; i<= n; ++i){
mm[i]= i & (i-1) ? mm[i-1] : mm[i-1]+1;
sptb[i][0]= b[i];
}
for (int j= 1; j<= mm[n]; ++j){
for (int i= 1; i+(1<<j)-1<= n; ++i){
sptb[i][j]= max(sptb[i][j-1], sptb[i+(1<<(j-1))][j-1]);
}
}
}
inline int AuxQuery(int x, int y)
{
int k= mm[y-x+1];
return max(sptb[x][k], sptb[y-(1<<k)+1][k]);
}
int Query(int l, int r)
{
int id_l= hs[l], id_r= hs[r];
if (id_l== id_r){
return r-l+1;
}
int t= max(R[l]-l+1, r-L[r]+1);
if (1< id_r-id_l){
t= max(t, AuxQuery(id_l+1, id_r-1));
}
return t;
}
int main(int argc, char const *argv[])
{
int n, q;
while (~scanf("%d", &n) && n){
scanf("%d", &q);
for (int i= 1; i<= n; ++i){
scanf("%d", a+i);
}
int tot= 1, th= 1;
for (int i= 1; i<= n; ++i){
if (i> 1 && a[i]!= a[i-1]){
for (int j= th; j< i; ++j){
L[j]= th;
R[j]= i-1;
}
b[tot]= i-th;
th= i;
++tot;
}
hs[i]= tot;
}
for (int j= th; j<= n; ++j){
L[j]= th;
R[j]= n;
}
b[tot]= n+1-th;
InitRMQ(tot, b);
while (q--){
int l, r;
scanf("%d %d", &l, &r);
printf("%d\n", Query(l, r));
}
}
return 0;
}