zoukankan      html  css  js  c++  java
  • UESTC 1425 Another LCIS

    UESTC_1425

        更多和区间合并相关的线段树问题可以参考胡浩的博客:http://www.notonlysuccess.com/index.php/segment-tree-complete/

        这个题和HDU_3308很像,只不过要多处理一下区间加和的操作,为了能够方便的修改、获取左区间的右端点和右区间左端点的大小关系,可以用两个标记lx[]、rx[]分别表示当前区间左端点以及右端点的值。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 100010
    int N, Q, a[MAXD], lc[4 * MAXD], rc[4 * MAXD], lx[4 * MAXD], rx[4 * MAXD], mc[4 * MAXD], add[4 * MAXD];
    int getmax(int x, int y)
    {
        return x > y ? x : y;
    }
    void update(int cur, int x, int y)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
        mc[cur] = getmax(mc[ls], mc[rs]);
        lc[cur] = lc[ls], rc[cur] = rc[rs];
        if(rx[ls] < lx[rs])
        {
            if(rc[ls] + lc[rs] > mc[cur])
                mc[cur] = rc[ls] + lc[rs];
            if(lc[ls] == mid - x + 1)
                lc[cur] += lc[rs];
            if(rc[rs] == y - mid)
                rc[cur] += rc[ls];
        }
        lx[cur] = lx[ls], rx[cur] = rx[rs];
    }
    void pushdown(int cur)
    {
        int ls = cur << 1, rs = (cur << 1) | 1;
        if(add[cur])
        {
            add[ls] += add[cur], add[rs] += add[cur];
            lx[ls] += add[cur], rx[ls] += add[cur];
            lx[rs] += add[cur], rx[rs] += add[cur];
            add[cur] = 0;
        }
    }
    void build(int cur, int x, int y)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
        add[cur] = 0;
        if(x == y)
        {
            mc[cur] = lc[cur] = rc[cur] = 1;
            lx[cur] = rx[cur] = a[x];
            return ;
        }
        build(ls, x, mid);
        build(rs, mid + 1, y);
        update(cur, x, y);
    }
    void init()
    {
        int i, j, k;
        scanf("%d%d", &N, &Q);
        for(i = 1; i <= N; i ++)
            scanf("%d", &a[i]);
        build(1, 1, N);
    }
    int query(int cur, int x, int y, int s, int t, int fa, int &ans)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
        if(x >= s && y <= t)
        {
            if(mc[cur] > ans)
                ans = mc[cur];
            return fa == -1 ? lc[cur] : rc[cur];
        }
        pushdown(cur);
        if(mid >= t)
            return query(ls, x, mid, s, t, -1, ans);
        else if(mid + 1 <= s)
            return query(rs, mid + 1, y, s, t, 1, ans);
        else
        {
            int ln = query(ls, x, mid, s, t, 1, ans), rn = query(rs, mid + 1, y, s, t, -1, ans);
            if(rx[ls] < lx[rs])
            {
                if(ln + rn > ans)
                    ans = ln + rn;
                if(fa == -1)
                    return lc[ls] == mid - x + 1 ? lc[ls] + rn : lc[ls];
                else
                    return rc[rs] == y - mid ? rc[rs] + ln : rc[rs];
            }
            return fa == -1 ? lc[ls] : rc[rs];
        }
    }
    void refresh(int cur, int x, int y, int s, int t, int v)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
        if(x >= s && y <= t)
        {
            add[cur] += v, lx[cur] += v, rx[cur] += v;
            return ;
        }
        pushdown(cur);
        if(mid >= s)
            refresh(ls, x, mid, s, t, v);
        if(mid + 1 <= t)
            refresh(rs, mid + 1, y, s, t, v);
        update(cur, x, y);
    }
    void solve()
    {
        int i, j, k, x, y, z, ans;
        char b[5];
        for(i = 0; i < Q; i ++)
        {
            scanf("%s", b);
            if(b[0] == 'q')
            {
                scanf("%d%d", &x, &y);
                ans = 0;
                query(1, 1, N, x, y, -1, ans);
                printf("%d\n", ans);
            }
            else
            {
                scanf("%d%d%d", &x, &y, &z);
                refresh(1, 1, N, x, y, z);
            }
        }
    }
    int main()
    {
        int t, tt;
        scanf("%d", &t);
        for(tt = 0; tt < t; tt ++)
        {
            init();
            printf("Case #%d:\n", tt + 1);
            solve();
        }
        return 0;
    }
  • 相关阅读:
    结对编程第一次作业
    软件工程第三次作业
    软件工程第二次作业
    软件工程第一次作业
    第五次作业(结对第2次)
    第四次作业
    第三次作业
    第二次作业(多图预警)
    第一次作业
    软工第四次作业——结对编程二
  • 原文地址:https://www.cnblogs.com/staginner/p/2447564.html
Copyright © 2011-2022 走看看