LCIS
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9713 Accepted Submission(s): 4215
Problem Description
Given n integers.
You have two operations:
U A B: replace the Ath number by B. (index counting from 0)
Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b].
Input
T in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=105).
The next line has n integers(0<=val<=105).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=105)
OR
Q A B(0<=A<=B< n).
Output
For each Q, output the answer.
Sample Input
1
10 10
7 7 3 3 5 9 9 8 1 8
Q 6 6
U 3 4
Q 0 1
Q 0 5
Q 4 7
Q 3 5
Q 0 2
Q 4 6
U 6 10
Q 0 9
Sample Output
1
1
4
2
3
1
2
5
题意:求区间连续递增的最大个数,Q是询问区间内最大的LCIS
U是更新节点
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int maxn = 1e5 + 6; int llen[maxn << 2], rlen[maxn << 2], len[maxn << 2], tree[maxn]; void pushup(int l, int r, int id) { int m = (l + r) >> 1; llen[id] = llen[id << 1]; rlen[id] = rlen[id << 1 | 1]; if (tree[m + 1] > tree[m]) { if (llen[id << 1] == m - l + 1) llen[id] += llen[id << 1 | 1]; if (rlen[id << 1 | 1] == r - m) rlen[id] += rlen[id << 1]; len[id] = max(max(len[id << 1], len[id << 1 | 1]), rlen[id << 1] + llen[id << 1 | 1]); } else len[id] = max(len[id << 1], len[id << 1 | 1]); } void build(int l, int r, int id) { if (l == r) { scanf("%d", &tree[l]); len[id] = llen[id] = rlen[id] = 1; return; } int m = (l + r) >> 1; build(l,m,id<<1); build(m+1,r,id<<1|1); pushup(l, r, id); } int query(int ll, int rr, int l, int r, int id) { if (ll <= l && r <= rr) return len[id]; int m = (l + r) >> 1; if (ll <= m && m < rr) { int l1 = query(ll, rr, l,m,id<<1); int l2 = query(ll, rr, m+1,r,id<<1|1); if (tree[m] < tree[m + 1]) { int le = max(ll, m - rlen[id << 1] + 1); int ri = min(rr, m + llen[id << 1 | 1]); return max(max(l1, l2), ri - le + 1); } return max(l1, l2); } else if (rr <= m) return query(ll, rr, l,m,id<<1); else return query(ll, rr, m+1,r,id<<1|1); } void update(int a, int b, int l, int r, int id) { if (a == l && a == r)//找到要更新的位置 { tree[a] = b; return; } int m = (l + r) >> 1; if (m >= a) update(a, b, l,m,id<<1); else update(a, b, m+1,r,id<<1|1); pushup(l, r, id); } int main() { int t; scanf("%d\n", &t); while (t--) { int n, m; scanf("%d%d", &n, &m); build(0, n - 1, 1); while (m--) { char c[5]; int a, b; scanf("%s %d %d", c, &a, &b); if (c[0] == ‘Q‘) printf("%d\n", query(a, b, 0, n - 1, 1)); else update(a, b, 0, n - 1, 1); } } return 0; }
原文地址:https://www.cnblogs.com/-citywall123/p/11066942.html