• HDU


    LCIS

    Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 8225 Accepted Submission(s): 3524


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

    Sample Output
    1
    1
    4
    2
    3
    1
    2
    5

    Author
    shǎ崽

    Source
    HDOJ Monthly Contest – 2010.02.06

    题意:

    两种操作,一种单点修改值,第二种查询区间最长连续上升子序列长度。

    思路一:

    用L[i]存储总体序列中以第i个位置结尾的LICS长度。用线段树维护这个L的区间最大值,更改i位置值的时候他会影响到L[i],以及i以后的一段区间,这段区间是连续上升的,我们可以二分求出这段区间,然后再线段树区间更改他。查询的时候需要特殊考虑查询区间的最长上升前缀,再线段树查询剩的区间的L最大值,复杂度m*(logn)^2。

      1 #include <iostream>
      2 #include <fstream>
      3 #include <sstream>
      4 #include <cstdlib>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <string>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <queue>
     11 #include <stack>
     12 #include <vector>
     13 #include <set>
     14 #include <map>
     15 #include <list>
     16 #include <iomanip>
     17 #include <cctype>
     18 #include <cassert>
     19 #include <bitset>
     20 #include <ctime>
     21 
     22 using namespace std;
     23 
     24 #define pau system("pause")
     25 #define ll long long
     26 #define pii pair<int, int>
     27 #define pb push_back
     28 #define mp make_pair
     29 #define clr(a, x) memset(a, x, sizeof(a))
     30 
     31 const double pi = acos(-1.0);
     32 const int INF = 0x3f3f3f3f;
     33 const int MOD = 1e9 + 7;
     34 const double EPS = 1e-9;
     35 
     36 /*
     37 #include <ext/pb_ds/assoc_container.hpp>
     38 #include <ext/pb_ds/tree_policy.hpp>
     39 
     40 using namespace __gnu_pbds;
     41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
     42 */
     43 
     44 int t, n, m, val[100015], L[100015];
     45 int Ma[400015], lazy[400015];
     46 void pushup(int i) {
     47     Ma[i] = max(Ma[i << 1], Ma[i << 1 | 1]);
     48 }
     49 void pushdown(int i) {
     50     if (lazy[i]) {
     51         Ma[i << 1] += lazy[i];
     52         Ma[i << 1 | 1] += lazy[i];
     53         lazy[i << 1] += lazy[i];
     54         lazy[i << 1 | 1] += lazy[i];
     55         lazy[i] = 0;
     56     }
     57 }
     58 void build(int i, int l, int r) {
     59     lazy[i] = 0;
     60     if (l == r) {
     61         Ma[i] = L[l];
     62         return;
     63     }
     64     int mi = l + r >> 1;
     65     build(i << 1, l, mi);
     66     build(i << 1 | 1, mi + 1, r);
     67     pushup(i);
     68 }
     69 void update(int i, int l, int r, int x, int y, int z) {
     70     if (x <= l && r <= y) {
     71         Ma[i] += z;
     72         lazy[i] += z;
     73         return;
     74     }
     75     pushdown(i);
     76     int mi = l + r >> 1;
     77     if (x <= mi) update(i << 1, l, mi, x, y, z);
     78     if (mi < y) update(i << 1 | 1, mi + 1, r, x, y, z);
     79     pushup(i);
     80 }
     81 int query(int i, int l, int r, int x, int y) {
     82     if (x <= l && r <= y) {
     83         return Ma[i];
     84     }
     85     pushdown(i);
     86     int res1 = 0, res2 = 0, mi = l + r >> 1;
     87     if (x <= mi) res1 = query(i << 1, l, mi, x, y);
     88     if (mi < y) res2 = query(i << 1 | 1, mi + 1, r, x, y);
     89     return max(res1, res2);
     90 }
     91 //#define local
     92 int main() {
     93 #ifdef local
     94     freopen("data.in", "r", stdin);
     95     freopen("data.out", "w", stdout);
     96 #endif // local
     97     scanf("%d", &t);
     98     val[0] = -1, L[0] = 0;
     99     while (t--) {
    100         scanf("%d%d", &n, &m);
    101         for (int i = 1; i <= n; ++i) {
    102             scanf("%d", &val[i]);
    103             if (val[i] > val[i - 1]) {
    104                 L[i] = L[i - 1] + 1;
    105             } else {
    106                 L[i] = 1;
    107             }
    108         }
    109         build(1, 1, n);
    110         while (m--) {
    111             char op;
    112             int a, b;
    113             scanf(" %c %d%d", &op, &a, &b);
    114             if ('U' == op) {
    115                 ++a;
    116                 L[a] = query(1, 1, n, a, a);
    117                 int pre_l = L[a], pre_v = val[a];
    118                 val[a] = b;
    119                 if (a > 1) {
    120                     L[a - 1] = query(1, 1, n, a - 1, a - 1);
    121                 }
    122                 L[a] = (val[a] > val[a - 1] ? L[a - 1] + 1 : 1);
    123                 update(1, 1, n, a, a, L[a] - pre_l);
    124                 if (a == n) continue;
    125                 int s = a + 1, e = n, mi, pos;
    126                 L[a + 1] = query(1, 1, n, a + 1, a + 1);
    127                 while (s <= e) {
    128                     mi = s + e >> 1;
    129                     L[mi] = query(1, 1, n, mi, mi);
    130                     if (L[mi] - L[a + 1] == mi - a - 1) {
    131                         s = (pos = mi) + 1;
    132                     } else {
    133                         e = mi - 1;
    134                     }
    135                 }
    136                 if (pre_v < val[a + 1] && val[a] >= val[a + 1]) {
    137                     update(1, 1, n, a + 1, pos, -pre_l); // pre_l换成 L[a] 不对
    138                 } else if (pre_v >= val[a + 1] && val[a] < val[a + 1]) {
    139                     update(1, 1, n, a + 1, pos, L[a]);
    140                 } else if (val[a] < val[a + 1]) {
    141                     update(1, 1, n, a + 1, pos, L[a] - pre_l);
    142                 }
    143             } else {
    144                 ++a, ++b;
    145                 int s = a, e = b, mi, pos1 = b + 1, pos2 = a - 1;
    146                 L[a] = query(1, 1, n, a, a);
    147                 while (s <= e) {
    148                     mi = s + e >> 1;
    149                     L[mi] = query(1, 1, n, mi, mi);
    150                     if (mi - a == L[mi] - L[a]) {
    151                         s = mi + 1;
    152                     } else {
    153                         e = (pos1 = mi) - 1;
    154                     }
    155                 }
    156                 int ans = pos1 - a;
    157                 if (pos1 <= b) {
    158                     int res = query(1, 1, n, pos1, b);
    159                     ans = max(ans, res);
    160                 }
    161                 printf("%d
    ", ans);
    162             }
    163         }
    164     }
    165     return 0;
    166 }
    167 /*
    168 2
    169 10 6
    170 1 3 6 2 7 4 3 5 6 6
    171 Q 0 9
    172 U 2 1
    173 Q 1 4
    174 U 5 1
    175 Q 2 8
    176 Q 5 7
    177 */

     思路二:

    刚学习到这是一类经典的线段树区间合并问题。线段树节点可以维护三个值,区间内最大连续子串,包含左端点的最大连续子串,包含右端点的最大连续子串,pushup向上维护父节点信息的时候都可以通过这三个值维护出来,同时对query函数做几乎一样的分类讨论处理就行了,复杂度mlogn。

      1 #include <iostream>
      2 #include <fstream>
      3 #include <sstream>
      4 #include <cstdlib>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <string>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <queue>
     11 #include <stack>
     12 #include <vector>
     13 #include <set>
     14 #include <map>
     15 #include <list>
     16 #include <iomanip>
     17 #include <cctype>
     18 #include <cassert>
     19 #include <bitset>
     20 #include <ctime>
     21 
     22 using namespace std;
     23 
     24 #define pau system("pause")
     25 #define ll long long
     26 #define pii pair<int, int>
     27 #define pb push_back
     28 #define mp make_pair
     29 #define clr(a, x) memset(a, x, sizeof(a))
     30 
     31 const double pi = acos(-1.0);
     32 const int INF = 0x3f3f3f3f;
     33 const int MOD = 1e9 + 7;
     34 const double EPS = 1e-9;
     35 
     36 /*
     37 #include <ext/pb_ds/assoc_container.hpp>
     38 #include <ext/pb_ds/tree_policy.hpp>
     39 
     40 using namespace __gnu_pbds;
     41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
     42 */
     43 
     44 int t, n, m, val[100015];
     45 struct node {
     46     int Ma, Ma_l, Ma_r;
     47     node () {}
     48     node (int Ma, int Ma_l, int Ma_r) : Ma(Ma), Ma_l(Ma_l), Ma_r(Ma_r) {}
     49 } Node[400015];
     50 void pushup(int i, int l, int r) {
     51     int mi = l + r >> 1, lson = i << 1, rson = i << 1 | 1;
     52     Node[i].Ma_l = Node[lson].Ma_l;
     53     Node[i].Ma_r = Node[rson].Ma_r;
     54     Node[i].Ma = max(Node[lson].Ma, Node[rson].Ma);
     55     if (val[mi] < val[mi + 1]) {
     56         if (Node[lson].Ma_l == mi - l + 1) {
     57             Node[i].Ma_l = Node[lson].Ma_l + Node[rson].Ma_l;
     58         }
     59         if (Node[rson].Ma_r == r - mi) {
     60             Node[i].Ma_r = Node[rson].Ma_r + Node[lson].Ma_r;
     61         }
     62         Node[i].Ma = max(Node[i].Ma, Node[lson].Ma_r + Node[rson].Ma_l);
     63     }
     64 }
     65 void build(int i, int l, int r) {
     66     if (l == r) {
     67         Node[i] = node(1, 1, 1);
     68         return;
     69     }
     70     int mi = l + r >> 1;
     71     build(i << 1, l, mi);
     72     build(i << 1 | 1, mi + 1, r);
     73     pushup(i, l, r);
     74 }
     75 void update(int i, int l, int r, int p, int z) {
     76     if (l == r) {
     77         val[l] = z;
     78         return;
     79     }
     80     int mi = l + r >> 1;
     81     if (p <= mi) update(i << 1, l, mi, p, z);
     82     if (mi < p) update(i << 1 | 1, mi + 1, r, p, z);
     83     pushup(i, l, r);
     84 }
     85 node query(int i, int l, int r, int x, int y) {
     86     if (x <= l && r <= y) {
     87         return Node[i];
     88     }
     89     int mi = l + r >> 1;
     90     node ans, res1, res2;
     91     ans = res1 = res2 = node(0, 0, 0);
     92     if (x <= mi) res1 = query(i << 1, l, mi, x, y);
     93     if (mi < y) res2 = query(i << 1 | 1, mi + 1, r, x, y);
     94     ans.Ma = max(res1.Ma, res2.Ma);
     95     ans.Ma_l = res1.Ma_l, ans.Ma_r = res2.Ma_r;
     96     if (x <= mi && mi < y && val[mi] < val[mi + 1]) {
     97         ans.Ma = max(ans.Ma, res1.Ma_r + res2.Ma_l);
     98         if (res1.Ma_l == mi - l + 1) {
     99             ans.Ma_l = res1.Ma_l + res2.Ma_l;
    100         }
    101         if (res2.Ma_r == r - mi) {
    102             ans.Ma_r = res1.Ma_r + res2.Ma_r;
    103         }
    104     }
    105     return ans;
    106 }
    107 void print() {
    108     for (int i = 1; i <= n << 2; ++i) {
    109         printf("Node[%d].Ma = %d, Ma_l = %d, Ma_r = %d ", i, Node[i].Ma, Node[i].Ma_l, Node[i].Ma_r);
    110         if (i % 2 == 0) puts("");
    111     }
    112     for (int i = 1; i <= n; ++i) printf("%d ", val[i]);
    113     puts("");
    114 }
    115 int main() {
    116     scanf("%d", &t);
    117     while (t--) {
    118         scanf("%d%d", &n, &m);
    119         for (int i = 1; i <= n; ++i) scanf("%d", &val[i]);
    120         build(1, 1, n);
    121         while (m--) {
    122             char op;
    123             int x, y;
    124             scanf(" %c%d%d", &op, &x, &y);
    125             if ('U' == op) {
    126                 update(1, 1, n, ++x, y);
    127             } else {
    128                 printf("%d
    ", query(1, 1, n, ++x, ++y).Ma);
    129             }
    130         }
    131     }
    132     return 0;
    133 }

    废话:最近的代码总坑在几处细微甚至不该错的地方,而且好久都调不出来,最近确实有些累了,状态不太好,更主要的还是练得不够呀...

  • 相关阅读:
    通过索引优化sql
    索引概述
    Spring整合Mybatis
    Mybatis逆向工程
    Mybatis级联
    Mybatis动态语句
    Mybatis—curd
    (转)最大似然估计&贝叶斯估计
    筛法求质——poj2262&2909
    (转)poj1182食物链
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/8493581.html
Copyright © 2020-2023  润新知