zoukankan      html  css  js  c++  java
  • LCIS HDU

    LCIS HDU - 3308 

    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]. 

    InputT in the first line, indicating the case number. 
    Each case starts with two integers n , m(0<n,m<=10 5). 
    The next line has n integers(0<=val<=10 5). 
    The next m lines each has an operation: 
    U A B(0<=A,n , 0<=B=10 5
    OR 
    Q A B(0<=A<=B< n). 
    OutputFor 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
    个人思路:这道题应该算是线段树区间合并的板子题,关键就是明确区间合并时的逻辑关系就可以了
    我因为忽略区间内的最长连续上升序列有可能由子区间的区间内连续上升序列得到而错了好几次
      1 //线段树区间合并
      2 //关键:明确相邻区间合并时候的逻辑关系
      3 #include<bits/stdc++.h>
      4 #define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
      5 #define mem(a,x) memset(a,x,sizeof(a))
      6 #define lson rt<<1,l,mid
      7 #define rson rt<<1|1,mid + 1,r
      8 #define P pair<int,int>
      9 #define ull unsigned long long
     10 using namespace std;
     11 typedef long long ll;
     12 const int maxn = 1e5 + 10;
     13 const int inf = 0x3f3f3f3f;
     14 
     15 struct node
     16 {
     17     int l,r;
     18     int left ,right ,mid;
     19     int maxx;
     20 }tree[maxn << 2];
     21 
     22 int n,m;
     23 int arr[maxn];
     24 
     25 void Pushup(int rt)
     26 {
     27     tree[rt].left = tree[rt << 1].left;
     28     tree[rt].right = tree[rt << 1|1].right;
     29     bool flag = arr[tree[rt << 1|1].l] > arr[tree[rt << 1].r];
     30 
     31     if(tree[rt << 1|1].right == tree[rt << 1|1].r - tree[rt << 1|1].l + 1 && flag)
     32     {
     33         tree[rt].right += tree[rt << 1].right;
     34     }
     35     // 合并以左端点为头的最长序列
     36     
     37     if(tree[rt << 1].left == tree[rt << 1].r - tree[rt << 1].l + 1 && flag)
     38     {
     39         tree[rt].left += tree[rt << 1|1].left;
     40     }
     41     // 合并以右端点为尾的最长序列
     42     
     43     if(arr[tree[rt << 1|1].l] > arr[tree[rt << 1].r])
     44     {
     45         tree[rt].mid = tree[rt << 1].right + tree[rt << 1|1].left;
     46     }
     47     else
     48     {
     49         tree[rt].mid = max(tree[rt << 1].right , tree[rt << 1|1].left);
     50     }
     51     tree[rt].mid = max(tree[rt].mid , max(tree[rt << 1].mid,tree[rt << 1|1].mid)); 
     52     // 获得区间内的最长序列:可能由子区间构成 也可能从子区间得到
     53     tree[rt].maxx = max(tree[rt].mid, max(tree[rt].left , tree[rt].right));
     54 }
     55 
     56 void build(int rt ,int l ,int r)
     57 {
     58     tree[rt].l = l , tree[rt].r = r;
     59     if(l == r)
     60     {
     61         tree[rt].left = tree[rt].right = tree[rt].maxx = tree[rt].mid = 1;
     62         return;
     63     }
     64     int mid = l + r >> 1;
     65     build(lson);
     66     build(rson);
     67     Pushup(rt);
     68 }
     69 
     70 void update(int rt ,int k ,int v)
     71 {
     72     if(tree[rt].l == k && tree[rt].r == k)
     73     {
     74         arr[k] = v;
     75         tree[rt].left = tree[rt].right = tree[rt].maxx = tree[rt].mid = 1;
     76         return;
     77     }
     78     int mid = tree[rt].l + tree[rt].r >> 1;
     79     if(mid >= k)
     80     {
     81         update(rt << 1 , k , v);
     82     }
     83     else
     84     {
     85         update(rt << 1|1 , k , v);
     86     }
     87     Pushup(rt);
     88 }
     89 
     90 int query(int rt , int l ,int r)
     91 {
     92     if(tree[rt].l == l && tree[rt].r == r)
     93     {
     94         return tree[rt].maxx;
     95     }
     96     int mid = tree[rt].l + tree[rt].r >> 1;
     97     if(mid >= r)
     98     {
     99         return query(rt << 1, l , r);
    100     }
    101     else if(mid < l )
    102     {
    103         return query(rt << 1|1 , l , r);
    104     }
    105     else
    106     {
    107         int m = min(mid - l + 1 , tree[rt << 1].right) + min(r - mid , tree[rt << 1|1].left);
    108         int left = query(rt<<1 ,l ,mid);
    109         int right = query(rt << 1|1 , mid + 1 , r);
    110         if(arr[tree[rt << 1].r] < arr[tree[rt << 1|1].l])
    111         {
    112             return max(m,max(left , right));
    113         }
    114         else
    115         {
    116             return max(left , right);
    117         }
    118     }
    119 }
    120 
    121 
    122 int main()
    123 {
    124     int T;
    125     scanf("%d",&T);
    126     while(T--)
    127     {
    128         //mem(arr,0);
    129         scanf("%d %d",&n,&m);
    130         for(int i = 1 ; i <= n ; ++ i)
    131         {
    132             scanf("%d",&arr[i]);
    133         }
    134         build(1,1,n);
    135         while(m -- )
    136         {
    137             char judge;
    138             int l,r;
    139             scanf(" %c %d %d",&judge ,&l , &r);
    140             if(judge == 'U')
    141             {
    142                 update(1,l + 1,r);
    143             }
    144             else
    145             {
    146                 printf("%d
    ",query(1,l + 1, r + 1));
    147             }
    148         }
    149     }
    150     return 0;
    151 }
    AC代码

    一个从很久以前就开始做的梦

  • 相关阅读:
    NC20565 生日礼物(双指针)
    NC20566 游戏(二分图)
    NC19833 地斗主(dp+矩阵快速幂)
    CF505C Mr. Kitayuta, the Treasure Hunter(dp)
    HDU5493 Queue(线段树)
    HDU5489 Removed Interval (LIS+分治)
    CF1158C Permutation recovery(线段树优化建图)
    NC20811 蓝魔法师(树形dp)
    NC20857 Xor Path(dfs)
    chrony同步时间
  • 原文地址:https://www.cnblogs.com/DreamACMer/p/11507785.html
Copyright © 2011-2022 走看看