zoukankan      html  css  js  c++  java
  • hdu3308—LCIS

    题目链接

      http://hdu.hustoj.com/showproblem.php?pid=3308

    问题描述
    给出n个整数,有两种操作
    1)U A B:用B取代第A个数(下标从0开始)
    2)Q A B:输出在[A,B]中最长连续递增子序列的长度
    分析
    给出一个序列,两种操作,分别是单点更新值和查询区间的最长连续递增子序列长
    度,典型的线段树问题
    首先考虑线段树的节点需要记录哪些值:
    1)包含左端点的最长连续递增子序列长度,记作pre[]
    2)包含右端点的最长连续递增子序列长度,记作suf[]
    3)整个区间的最长连续递增子序列长度,记作sub[]
    每次pushUp都需要自下而上更新这三个值。
    注意点:
    对于左连续,既可以由左儿子的左连续得来,也可能包含右儿子的左连续,这就要判断左儿子的左连续是否覆盖了整个区间,并且左儿子的最右值小于右儿子的最左值。同理对于右连续也是一样的。
    对于整个区间的LCIS,可能来源于左右儿子的最值(因为可能左儿子的最右值不小于右儿子的最左值),也可能来源于两个区间的中间部分。
    代码

      1 #include<stdio.h>
      2 const int maxn = 100010;
      3 int n, m, x, y;
      4 char ch[5];
      5 int val[maxn], sub[maxn * 4], pre[maxn * 4], suf[maxn * 4];
      6 
      7 int max(int a, int b)
      8 {
      9     return a > b ? a : b;
     10 }
     11 int min(int a, int b)
     12 {
     13     return a < b ? a : b;
     14 }
     15 
     16 void pushUp(int rt, int l, int r)
     17 {
     18     int m = (l + r) / 2;
     19 
     20     sub[rt] = max(sub[rt * 2], sub[rt * 2 + 1]);
     21     if(val[m] < val[m + 1])
     22         sub[rt] = max(sub[rt], suf[rt * 2] + pre[rt * 2 + 1]);
     23 
     24     pre[rt] = pre[rt * 2];
     25     if(pre[rt] == m - l + 1 && val[m] < val[m + 1])
     26         pre[rt] += pre[rt * 2 + 1];
     27 
     28     suf[rt] = suf[rt * 2 + 1];
     29     if(suf[rt] == r - m && val[m] < val[m + 1])
     30         suf[rt] += suf[rt * 2];
     31 }
     32 
     33 void build(int rt, int l, int r)
     34 {
     35     if(l == r)
     36     {
     37         sub[rt] = pre[rt] = suf[rt] = 1;
     38         return;
     39     }
     40     int m = (l + r) / 2;
     41     build(rt * 2, l, m);
     42     build(rt * 2 + 1, m + 1, r);
     43     pushUp(rt, l, r);
     44 }
     45 
     46 void update(int rt, int l, int r)
     47 {
     48     if(l == r)
     49         return;
     50     int m = (l + r) / 2;
     51     if(x <= m)
     52         update(rt * 2, l, m);
     53     else
     54         update(rt * 2 + 1, m + 1, r);
     55     pushUp(rt, l, r);
     56 }
     57 
     58 int query(int rt, int l, int r)
     59 {
     60     if(x <= l && y >= r)
     61         return sub[rt];
     62     int m = (l + r) / 2;
     63     if(y <= m)
     64         return query(rt * 2, l, m);
     65     if(x > m)
     66         return query(rt * 2 + 1, m + 1, r);
     67     int ans = max(query(rt * 2, l, m), query(rt * 2 + 1, m + 1, r));
     68     if(val[m] < val[m + 1])
     69     {
     70         ans = max(ans, min(suf[rt * 2], m - x + 1) + min(pre[rt * 2 + 1], y - m));
     71     }
     72     return ans;
     73 }
     74 int main()
     75 {
     76     int t;
     77     scanf("%d", &t);
     78     while(t--)
     79     {
     80         scanf("%d%d", &n, &m);
     81         for(int i = 1; i <= n; i++)
     82             scanf("%d", &val[i]);
     83         build(1, 1, n);
     84         while(m--)
     85         {
     86             scanf("%s%d%d", ch, &x, &y);
     87             x += 1;    //下标:0 1
     88             if(ch[0] == 'U')
     89             {
     90                 val[x] = y;
     91                 update(1, 1, n);
     92             }
     93             else if(ch[0] == 'Q')
     94             {
     95                 y += 1;
     96                 printf("%d
    ", query(1, 1, n));
     97             }
     98         }
     99     }
    100     return 0;
    101 }
  • 相关阅读:
    Apollo,Python,Delphi与Oracle之间的神话关系
    Delphi语言获得生命的原因和过程
    cocos2d(x) HTML label ;CCHTML CCHTMLLabel
    不重启使XP环境变量生效
    对当下纷繁乱世的思考框架(核心与边缘,时间与成本)
    晚明一出,明朝不必再穿越了
    常用的Linux终端
    如何发布使用LGPL版Qt的商业软件
    如何制作一个类似Tiny Wings的游戏 Cocos2d-x 2.1.4
    文明之火熊熊燃烧,灼热乃至引燃了周边霉湿的柴草
  • 原文地址:https://www.cnblogs.com/friend-A/p/10011356.html
Copyright © 2011-2022 走看看