zoukankan      html  css  js  c++  java
  • 线段树(区间合并) HDOJ 3308 LCIS

    题目传送门

    题意:线段树操作:1. 单点更新 2. 求区间的LCIS(longest consecutive increasing subsequence)

    分析:注意是连续的子序列,就是简单的区间合并,记录线段的端点的值,如果rx[rt<<1] < lx[rt<<1|1]就区间合并,最后结果保存在ms中。因为记录的数据较多,索性结构体内再开一个结构体,感觉还不错。写完这题,对区间合并的操作有了更深的理解。

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015/9/25 星期五 10:37:34
    * File Name     :G.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    const double EPS = 1e-8;
    struct ST   {
        struct Node {
            int lx, rx;
            int ls, rs, ms;
        }node[N<<2];
        void push_up(int l, int r, int rt)    {
            node[rt].ls = node[rt<<1].ls;   node[rt].rs = node[rt<<1|1].rs;
            node[rt].lx = node[rt<<1].lx;   node[rt].rx = node[rt<<1|1].rx;
            node[rt].ms = max (node[rt<<1].ms, node[rt<<1|1].ms);
            int mid = (l + r) >> 1;
            if (node[rt<<1].rx < node[rt<<1|1].lx)  {
                if (node[rt<<1].ls == mid - l + 1)  {
                    node[rt].ls += node[rt<<1|1].ls;
                }
                if (node[rt<<1|1].rs == r - mid)    {
                    node[rt].rs += node[rt<<1].rs;
                }
                node[rt].ms = max (node[rt].ms, node[rt<<1].rs + node[rt<<1|1].ls);
            }
        }
        void build(int l, int r, int rt)    {
            if (l == r) {
                scanf ("%d", &node[rt].lx);
                node[rt].rx = node[rt].lx;
                node[rt].ls = node[rt].rs = node[rt].ms = 1;
                return ;
            }
            int mid = (l + r) >> 1;
            build (lson);   build (rson);
            push_up (l, r, rt);
        }
        void updata(int p, int c, int l, int r, int rt) {
            if (l == r) {
                node[rt].lx = node[rt].rx = c;  return ;
            }
            int mid = (l + r) >> 1;
            if (p <= mid)   updata (p, c, lson);
            else    updata (p, c, rson);
            push_up (l, r, rt);
        }
        int query(int ql, int qr, int l, int r, int rt) {
            if (ql <= l && r <= qr) {
                return node[rt].ms;
            }
            int mid = (l + r) >> 1, ret = 0;
            if (ql <= mid)  {
                ret = max (ret, query (ql, qr, lson));
            }
            if (qr > mid)   {
                ret = max (ret, query (ql, qr, rson));
            }
            if (node[rt<<1].rx < node[rt<<1|1].lx)  {
                ret = max (ret, min (mid - ql + 1, node[rt<<1].rs) + min (qr - mid, node[rt<<1|1].ls));
            }
            return ret;
        }
    }st;
    
    int main(void)    {
        int T;  scanf ("%d", &T);
        while (T--)   {
            int n, q;   scanf ("%d%d", &n, &q);
            st.build (1, n, 1);
            for (int a, b, i=1; i<=q; ++i)    {
                char s[2];   scanf ("%s%d%d", &s, &a, &b);
                if (s[0] == 'Q')  {
                    printf ("%d
    ", st.query (a + 1, b + 1, 1, n, 1));
                }
                else    {
                    st.updata (a + 1, b, 1, n, 1);
                }
            }
        }
    
        return 0;
    }
    

    新代码

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N = 1e5 + 5;
    
    #define lc o << 1
    #define rc o << 1 | 1
    
    int s[N<<2], sl[N<<2], sr[N<<2];
    int al[N<<2], ar[N<<2];
    int x[N];
    
    void push_up(int o, int l, int r) {
        sl[o] = sl[lc]; sr[o] = sr[rc];
        al[o] = al[lc]; ar[o] = ar[rc];
        s[o] = max(s[lc], s[rc]);
        int mid = l + r >> 1;
        if (ar[lc] < al[rc]) {
            s[o] = max(s[o], sr[lc]+sl[rc]);
            if (sl[o] == mid-l+1) sl[o] += sl[rc];
            if (sr[o] == r-mid) sr[o] += sr[lc];
        }
    }
    
    void build(int o, int l, int r) {
        if (l == r) {
            al[o] = ar[o] = x[l];
            s[o] = sl[o] = sr[o] = 1;
            return ;
        }
        int mid = l + r >> 1;
        build(lc, l, mid);
        build(rc, mid+1, r);
        push_up(o, l, r);
    }
    
    void modify(int o, int l, int r, int p, int v) {
        if (l == r) {
            al[o] = ar[o] = v;
            return ;
        }
        int mid = l + r >> 1;
        if (p <= mid) modify(lc, l, mid, p, v);
        else modify(rc, mid+1, r, p, v);
        push_up(o, l, r);
    }
    
    int query(int o, int l, int r, int ql, int qr) {
        if (ql <= l && r <= qr) return s[o];
        int mid = l + r >> 1, ret = 0;
        if (ql <= mid) ret = max(ret, query(lc, l, mid, ql, qr));
        if (qr > mid) ret = max(ret, query(rc, mid+1, r, ql, qr));
        if (ql <= mid && qr > mid) {
            if (ar[lc] < al[rc]) {
                ret = max(ret, min(sr[lc], mid-ql+1)+min(sl[rc], qr-mid));
            }
        }
        return ret;
    }
    
    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", &x[i]);
            }
            build(1, 1, n);
            char str[5];
            int a, b;
            while (m--) {
                scanf("%s%d%d", &str, &a, &b);
                if (str[0] == 'U') modify(1, 1, n, a+1, b);
                else printf("%d
    ", query(1, 1, n, a+1, b+1));
            }
        }
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    47. Permutations II
    56. Merge Intervals
    57. Insert Interval
    常见算法问题
    67. Unique Paths
    版权声明
    121. Best Time to Buy and Sell Stock
    Leetcode backtracking 合集
    转载 int和string 类型的互换
    prim算法,克鲁斯卡尔算法---最小生成树
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4837805.html
Copyright © 2011-2022 走看看