《算法竞赛入门经典-训练指南》P198 记录一下区间的左右边界就可以了 #include <iostream> #include <stack> #include <queue> #include <cstdio> #include <cstdlib> #include <cmath> #include <set> #include <vector> #include <cstring> #include <algorithm> #define INF 0x7fffffff #define N 100010 #define M 1000010 #define LL long long #define mod 95041567 using namespace std; int arr[N]; int num[N][3]; int dp[N][20]; void RMQ_init(int len){ for(int j = 1; (1 << j) <= len; ++ j) for(int i = 1; i + (1 << j) - 1 < len; ++ i) dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]); } int RMQ(int L, int R){ if(R < L) return 0; else if(R == L) return dp[R][0]; int k = 0; while((1 << (k + 1)) <= R - L + 1) ++ k; return max(dp[L][k], dp[R - (1 << k) + 1][k]); } int main() { int n, q; // freopen("in.txt","r",stdin); while(scanf("%d", &n) != EOF){ if(! n) break; scanf("%d", &q); for(int i = 0; i < n; ++ i) scanf("%d", &arr[i]); for(int i = 0; i <= n + 2; ++ i) for(int j = 0; j <= 20; ++ j) dp[i][j] = 0; arr[n] = INF; int p = 0; int len = 0; for(int i = 1; i <= n; ++ i) if(arr[i] != arr[i - 1]){ for(int j = p; j <= i - 1; ++ j){ num[j][0] = i - 1; num[j][1] = p; num[j][2] = len; } dp[len ++][0] = i - p; p = i; } RMQ_init(len); int L, R; for(int i = 0; i < q; ++ i){ scanf("%d %d", &L, &R); if(arr[L - 1] == arr[R - 1]){ printf("%d ", R - L + 1); continue; } //printf("%s ", "++"); p = num[L - 1][0] - (L - 1) + 1; p = max(p, R - num[R - 1][1]); p = max(p, RMQ(num[L - 1][2] + 1, num[R - 1][2] - 1)); printf("%d ", p); } } return 0; }