HDU-3308 LCIS

来源:互联网 发布:什么是数据架构 编辑:程序博客网 时间:2024/05/21 06:36

LCIS

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)


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
110 107 7 3 3 5 9 9 8 1 8 Q 6 6U 3 4Q 0 1Q 0 5Q 4 7Q 3 5Q 0 2Q 4 6U 6 10Q 0 9
 

Sample Output
11423125
 
————————————————————集训27.4的分割线————————————————————
思路:最长连续上升子序列。线段树之区间合并。存储长度。
查询:有效区间则返回最大长度。否则在三个值中找到最大值:
1. 左儿子长度
2. 右儿子长度
3. 左儿子和右儿子之间,在查询范围内的最大长度
更新:单点更新。
push_up:在区间可以合并(左边一半的尾巴接上右边一半的头)的时候,更新左起、右起以及该区间最大值。
P.S. 要知道两个点:
1. (l+r)>>1是左边一半的最后一个点 
2. m这个点总是在左儿子内
代码如下:
/*ID: j.sure.1PROG:LANG: C++*//****************************************/#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <stack>#include <queue>#include <vector>#include <map>#include <string>#include <climits>#include <iostream>#define INF 0x3f3f3f3fusing namespace std;/****************************************/#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1#define mid int m = (l + r) >> 1#define node int l, int r, int rtconst int N = 1e5+5;int a[N];struct Node {int left, right, maxi;}t[N<<2];void Up(int rt, int len, int m){Node &ll = t[rt<<1], &rr = t[rt<<1|1], &tt = t[rt];tt.left = ll.left;tt.right = rr.right;tt.maxi = max(ll.maxi, rr.maxi);//m是左边一半的最后一个结点if(a[m] < a[m+1]) {//可以进行区间合并if(tt.left == (len+1>>1)) tt.left += rr.left;if(tt.right == (len>>1)) tt.right += ll.right;tt.maxi = max(tt.maxi, ll.right + rr.left);}}void build(node){if(l == r) {t[rt].maxi = t[rt].left = t[rt].right = 1;return ;}mid;build(lson); build(rson);Up(rt, r-l+1, l+r>>1);}void update(int i, int c, node){if(l == r) {a[i] = c;return ;}mid;if(i <= m) update(i, c, lson);else update(i, c, rson);Up(rt, r-l+1, l+r>>1);}int query(int L, int R, node){Node &ll = t[rt<<1], &rr = t[rt<<1|1], &tt = t[rt];if(L <= l && r <= R) {return tt.maxi;}mid;int ret = 0;if(L <= m)ret = max(ret, query(L, R, lson));if(m < R)ret = max(ret, query(L, R, rson));if(a[m] < a[m+1])ret = max(ret, min(m-L+1, ll.right) + min(R-m, rr.left));//要知道m这个点总是在左儿子return ret;}int main(){#ifdef J_Sure//freopen("000.in", "r", stdin);//freopen(".out", "w", stdout);#endifint T;scanf("%d", &T);int n, m;while(T--) {scanf("%d%d", &n, &m);for(int i = 0 ; i < n; i++)scanf("%d", &a[i]);build(0, n, 1);char op[10];int A, B;while(m--) {scanf("%s %d %d", op, &A, &B);if(op[0] == 'Q') {printf("%d\n", query(A, B, 0, n, 1));}else {update(A, B, 0, n, 1);}}}return 0;}


0 0
原创粉丝点击