HDU 3308 LCIS (线段树~)

来源:互联网 发布:美图搜索软件 编辑:程序博客网 时间:2024/06/05 15:47

这个题花了很长很长很长时间才解决,感觉理解线段树需要对递归有很好的掌握才行,至于这个题的做法,以后有时间我会补上,一时半会很难说清楚。我需要更多的练习才能完全掌握这些思想,BTW,os真是越看越烦,看不下去就开始写题,写完还得看TAT

#include <stdio.h>#include <string.h>#include <iostream>using namespace std;#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1const int maxn = 100000 + 5;int msum[maxn << 2];int lsum[maxn << 2];int rsum[maxn << 2];int num[maxn];void pushup(int l, int r, int rt) {    lsum[rt] = lsum[2 * rt];    rsum[rt] = rsum[2 * rt + 1];    msum[rt] = max(msum[rt * 2], msum[rt * 2 + 1]);    int m = (l + r) >> 1;    int len = (r - l + 1);    if (num[m] < num[m + 1]) {        if (lsum[rt] == len - len / 2) lsum[rt] += lsum[2 * rt + 1];        if (rsum[rt] == len / 2) rsum[rt] += rsum[2 * rt];        msum[rt] = max(msum[rt], lsum[2 * rt + 1] + rsum[2 * rt]);    }}void update(int p, int l, int r, int rt) {    //只起到一个更新作用,修改值已经在主函数中修改了    if (l == r) return;    int m = (l + r) >> 1;    if (p <= m)        update(p, lson);    else        update(p, rson);    pushup(l, r, rt);}int query(int L, int R, int l, int r, int rt) {    if (L <= l && r <= R) return msum[rt];    int m = (l + r) >> 1;    if (R <= m) return query(L, R, lson);    if (L > m) return query(L, R, rson);    int a, b;    a = query(L, R, lson);    b = query(L, R, rson);    int ans = max(a, b);    if (num[m] < num[m + 1]) {        int c;        c = min(rsum[2 * rt], m - L + 1) + min(lsum[2 * rt + 1], R - m);        ans = max(c, ans);    }    return ans;}void build(int l, int r, int rt) {    if (l == r) {        lsum[rt] = rsum[rt] = msum[rt] = 1;        return;    }    else {        int m = (l + r) >> 1;        build(lson);        build(rson);        pushup(l, r, rt);    }}int main() {    int t;    scanf("%d", &t);    while (t--) {        int n, m;        scanf("%d%d", &n, &m);        for (int i = 1; i <= n; i++) {            scanf("%d", &num[i]);        }        build(1, n, 1);        while (m--) {            char op[121];            scanf("%s", op);            int a, b;            scanf("%d%d", &a, &b);            if (op[0] == 'U') {                a++;                num[a] = b;                update(a, 1, n, 1);            } else {                a++;                b++;                printf("%d\n", query(a, b, 1, n, 1));            }        }    }}