UESTC 1425 Another LCIS

来源:互联网 发布:如何接收大数据 编辑:程序博客网 时间:2024/05/16 10:33

大意:求区间最长连续上升序列。

思路:维护三个值。

1、左、右子树最长连续上升序列的最大值。

2、区间边界值,方便判断是否可以合并。

3、如果可以合并,有vr[lc] < vl[rc],则需记录左子树右边界可以到达的最左端,右子树左边界可以到达的最右端,求区间长度即可。

4、注意细节以及维护的值的更新条件。

#include <iostream>#include <cstdlib>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <vector>using namespace std;const int maxn = 100010;#define lc o*2#define rc o*2+1int n, m;/*分别是左、右区间最值,以及右边界能够到达的最左端,左边界能够到达的最右端*/int vl[maxn<<2], vr[maxn<<2], lmost[maxn<<2], rmost[maxn<<2];int maxv[maxn<<2];int addv[maxn<<2];void pushdown(int o){if(addv[o]){addv[lc] += addv[o];addv[rc] += addv[o];vl[lc] += addv[o], vr[lc] += addv[o];vl[rc] += addv[o], vr[rc] += addv[o];addv[o] = 0;}}void pushup(int o, int M){maxv[o] = max(maxv[lc], maxv[rc]);vl[o] = vl[lc], vr[o] = vr[rc];lmost[o] = lmost[rc], rmost[o] = rmost[lc];if(vr[lc] < vl[rc]){maxv[o] = max(maxv[o], rmost[rc]-lmost[lc]+1);if(rmost[o] >= M) rmost[o] = rmost[rc];if(lmost[o] <= M+1) lmost[o] = lmost[lc];}}void build(int o, int L, int R){addv[o] = 0;if(L == R){scanf("%d", &vl[o]);vr[o] = vl[o];lmost[o] = rmost[o] = L;maxv[o] = 1;return ;}int M = L + (R-L)/2;build(lc, L, M);build(rc, M+1, R);pushup(o, M);}void update(int o, int y1, int y2, int L, int R, int v){if(y1 <= L && y2 >= R){addv[o] += v;vl[o] += v, vr[o] += v;return ;}int M = L + (R-L)/2;pushdown(o);if(y1 <= M) update(lc, y1, y2, L, M, v);if(y2 > M) update(rc, y1, y2, M+1, R, v);pushup(o, M);}int query(int o, int y1, int y2, int L, int R){if(y1 <= L && y2 >= R) return maxv[o];int M = L + (R-L)/2, ans = 0;if(y2 <= M) return query(lc, y1, y2, L, M);if(y1 > M) return query(rc, y1, y2, M+1, R);ans = max(query(lc, y1, y2, L, M), query(rc, y1, y2, M+1, R));if(vr[lc] < vl[rc]) ans = max(ans, min(y2, rmost[rc]) - max(y1, lmost[lc])+1);return ans;}void read_case(){scanf("%d%d", &n, &m);build(1, 1, n);}void solve(){read_case();char op[5];int y1, y2, v;while(m--){scanf("%s%d%d", op, &y1, &y2);if(op[0] == 'q'){int ans = query(1, y1, y2, 1, n);printf("%d\n", ans);}else{scanf("%d", &v);update(1, y1, y2, 1, n, v);}}}int main(){int T, times = 0;scanf("%d", &T);while(T--){printf("Case #%d:\n", ++times);solve();}return 0;}


原创粉丝点击