传送门: HDU 3308
题解:
维护最大连续和左右连续
区间合并查询
/*
adrui's submission
Language : C++
Result : Accepted
Favorite : Dragon Balls
Love : yy
Motto : Choose & Quit
Standing in the Hall of Fame
*/
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn(100005);
#define debug 0
#define lowbit(x) (x & (-x))
#define ls rt << 1
#define rs rt << 1 | 1
#define M(a, b) memset(a, b, sizeof(a))
int n, m, c[maxn];
struct Node {
int l, r, ans;
}node[maxn << 2];
void pushUp(Node &q, Node a, Node b, int l, int r) { //??
q.l = a.l;
q.r = b.r;
q.ans = max(a.ans, b.ans);
int mid = (l + r) >> 1;
if (c[mid] < c[mid + 1]) {
if (q.l == mid - l + 1) q.l += b.l;
if (q.r == r - mid) q.r += a.r;
q.ans = max(q.ans, a.r + b.l);
}
}
void build(int rt, int l, int r) {
if (l == r) {
node[rt].ans = node[rt].r = node[rt].l = 1;
return;
}
int mid = (l + r) >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
pushUp(node[rt], node[rt << 1], node[rt << 1 | 1], l, r);
}
void update(int rt, int l, int r, int u, int v) {
if (l == r) {
c[l] = v;
return;
}
int mid = (l + r) >> 1;
if (u <= mid) update(ls, l, mid, u, v);
else update(rs, mid + 1, r, u, v);
pushUp(node[rt], node[rt << 1], node[rt << 1 | 1], l, r);
}
Node query(int rt, int l, int r, int ql, int qr) { //query
if (l == ql && qr == r) return node[rt];
int mid = (l + r) >> 1;
Node p, q, res;
if (ql <= mid && qr > mid) {
p = query(ls, l, mid, ql, mid);
q = query(rs, mid + 1, r, mid + 1, qr);
pushUp(res, p, q, l, r);
}
else {
if (ql <= mid) res = query(ls, l, mid, ql, qr);
else res = query(rs, mid + 1, r, ql, qr);
}
return res;
}
int main() {
#if debug
freopen("in.txt", "r", stdin);
#endif //debug
cin.tie(0);
cin.sync_with_stdio(false);
int t, lt, rt;
cin >> t;
char s[5];
while (t--) {
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> c[i];
M(node, 0);
build(1, 1, n);
while (m--) {
cin >> s >> lt >> rt;
if (s[0] == 'Q') {
Node Ans = query(1, 1, n, lt + 1, rt + 1); // ???0??
cout << Ans.ans << endl;
}
else {
update(1, 1, n, lt + 1, rt);
}
}
}
return 0;
}