Description
给定一个序列A[i],每次询问l,r,求[l,r]内最长子串,使得该子串为不上升子串或不下降子串。
Solution
线段树维护左边、中间、右边的最长不升/降子串,pushup时维护一下即可。
Code
/************************************************
* Au: Hany01
* Prob: bzoj4491
* Inst: Yali High School
************************************************/
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++ i)
#define For(i, j, k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define x first
#define y second
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define SZ(a) ((int)(a).size())
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define y1 wozenmezhemecaia
template <typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
inline int read() {
static int _, __; static char c_;
for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar()) if (c_ == '-') __ = -1;
for ( ; c_ >= '0' && c_ <= '9'; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
return _ * __;
}
const int maxn = 5e4 + 5;
int n, a[maxn];
struct Item {
int il, ir, im, dl, dr, dm, l, r;
}tr[maxn << 2];
#define mid ((l + r) >> 1)
#define lc (t << 1)
#define rc (lc | 1)
inline Item merge(Item L, Item R) {
static Item M;
M.l = L.l, M.r = R.r;
M.il = L.il, M.ir = R.ir, M.dl = L.dl, M.dr = R.dr, M.im = max(L.im, R.im), M.dm = max(L.dm, R.dm);
if (a[L.r] <= a[R.l]) {
chkmax(M.im, L.ir + R.il);
if (L.il == L.r - L.l + 1) M.il = L.il + R.il;
if (R.ir == R.r - R.l + 1) M.ir = R.ir + L.ir;
}
if (a[L.r] >= a[R.l]) {
chkmax(M.dm, L.dr + R.dl);
if (L.dl == L.r - L.l + 1) M.dl = L.dl + R.dl;
if (R.dr == R.r - R.l + 1) M.dr = R.dr + L.dr;
}
return M;
}
void build(int t, int l, int r) {
if (l == r) {
a[l] = read(), tr[t].l = l, tr[t].r = r,
tr[t].il = tr[t].ir = tr[t].im = tr[t].dl = tr[t].dr = tr[t].dm = 1;
return;
}
build(lc, l, mid), build(rc, mid + 1, r), tr[t] = merge(tr[lc], tr[rc]);
}
Item query(int t, int l, int r, int x, int y) {
if (x <= l && r <= y) return tr[t];
if (y <= mid) return query(lc, l, mid, x, y);
if (x > mid) return query(rc, mid + 1, r, x, y);
return merge(query(lc, l, mid, x, y), query(rc, mid + 1, r, x, y));
}
int main()
{
#ifdef hany01
freopen("bzoj4491.in", "r", stdin);
freopen("bzoj4491.out", "w", stdout);
#endif
n = read(), build(1, 1, n);
for (static int m = read(), l, r; m --; ) {
register Item t;
l = read(), r = read(), t = query(1, 1, n, l, r), printf("%d\n", max(t.im, t.dm));
}
return 0;
}