由于要使用ST算法,因此在计算出每个区间大小之后要进行初始化,这样就可以在O(1)的时间内回答出上述第三种情况的中间区间的长度的最大值。
#include <iostream> #include <cmath> #include <cstdio> using namespace std; const int N = 100005; struct Seg { int beg; int end; }; int num[N]; int pos[N]; Seg seg[N]; int dpmax[N][30]; int segcount; int n, q; const double log_2 = log(2.0); inline int Max(int x, int y) {return x > y ? x : y;} void rmqinit() { for (int i = 0; i <= segcount; ++i) dpmax[i][0] = seg[i].end - seg[i].beg + 1; for (int j = 1; (1 << j) <= segcount; ++j) { int t = 1 << j; for (int i = 0; i + t - 1 <= segcount; ++i) { dpmax[i][j] = Max(dpmax[i][j - 1], dpmax[i + (t >> 1)][j - 1]); } } } int rmqgetmax(int beg, int end) { int t = (int)(log(double(end - beg + 1)) / log_2); return Max(dpmax[beg][t], dpmax[end - (1 << t) + 1][t]); } int main() { int beg, end, ans; num[0] = 1000000; while (scanf("%d", &n) != EOF && n) { scanf("%d", &q); segcount = 0; for (int i = 1; i <= n; ++i) { scanf("%d", num + i); if (num[i] != num[i - 1]) { segcount++; pos[i] = segcount; seg[segcount].beg = seg[segcount].end = i; } else { pos[i] = segcount; seg[segcount].end++; } } rmqinit(); while (q--) { scanf("%d%d", &beg, &end); if (pos[end] == pos[beg]) ans = end - beg + 1; else if (pos[end] - pos[beg] == 1) ans = Max(seg[pos[beg]].end - beg + 1, end - seg[pos[end]].beg + 1); else { ans = Max(seg[pos[beg]].end - beg + 1, end - seg[pos[end]].beg + 1); ans = Max(ans, rmqgetmax(pos[beg] + 1, pos[end] - 1)); } printf("%d\n", ans); } } return 0; }