思路:这个是RMQ变形,因为这个是一个non-decreasing order序列,所以同一个数是连续的,那么我们可以先处理下每个连续的数的左右边界,也就是l[i],r[i]的值,num[i]表示当前位置的数所属段的标号。对每种数进行编号,也就是每个段。建立Segment-Tree,再就是询问的时候,因为给的是原坐标,所以要转换成所属的段标号,如果是同一个段,那么直接坐标相减+1,否则就进行RMQ的询问,这里要注意两端的情况,看下面代码吧。
// #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> // #define DEBUG #ifdef DEBUG #define debug(...) printf( __VA_ARGS__ ) #else #define debug(...) #endif #define MEM(x,y) memset(x, y,sizeof x) #define lson(x) ((x) << 1) #define rson(x) ((x<<1)|1) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 1e5 + 10; int cnt[maxn], l[maxn], r[maxn], val[maxn], num[maxn]; int a[maxn]; int dp[maxn][30]; void RMQ_Init(int t){ int n = t; for (int i = 0;i < n;i++) dp[i][0] = cnt[i]; for (int j = 1;(1 << j) <= n;j++){ for (int i = 0;i + (1 << j) - 1 < n;i++) dp[i][j] = max(dp[i][j-1],dp[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(dp[L][k],dp[R-(1<<k)+1][k]); } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int n,q; while(scanf("%d",&n) && n){ scanf("%d",&q); for (int i = 0;i < n;i++) scanf("%d",&a[i]); MEM(cnt, 0); MEM(l, 0); MEM(r, 0); int t = 0, tmp = 1; for (int i = 1;i < n - 1;i++){//预处理 if (a[i] != a[i - 1]){ cnt[t] = tmp; r[t] = i - 1;//当前段的右值 t++;//段的标号 num[i] = t;//当前位置的数所属段的标号 l[t] = i;//下个段的左值 tmp = 1;//计数 }else { tmp++; num[i] = t; } } r[t] = n - 1; cnt[t] = tmp; num[n-1] = t; RMQ_Init(t);//建立线段树 while(q--){ int x,y; scanf("%d%d",&x,&y); x--,y--; int L = num[x], R = num[y]; if (L == R){ printf("%d\n",y-x+1); continue; } int Max = 0; Max = max(r[L]-x+1,y-l[R]+1); if (R -1 >= L+1) Max = max(Max,RMQ(L+1,R-1)); printf("%d\n",Max); } } return 0; }