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代码

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

  • 相关阅读:
    如何选择Html.RenderPartial和Html.RenderAction
    [转]使用 HTML5 WebSocket 构建实时 Web 应用
    基于.NET平台常用的框架整理
    0303
    XMLHTTP
    0120如何合并两个使用 System.Xml 使用 Visual C#.NET 的 XML 文档中的数据
    后台动态创建datatable0115
    笔记1126ASP.NET面试题(转)
    笔记1015
    数组与ARRAYLIST的关系与区别(转)
  • 原文地址:https://www.cnblogs.com/DreamACMer/p/11507785.html
Copyright © 2011-2022 走看看