zoukankan      html  css  js  c++  java
  • hdu 3308 LCIS

    最近开始线段树一段时间了,也发现了不少大牛的博客比如HH大牛  ,小媛姐。这个题目是我在看HH大牛的线段树专题是给出的习题,(可以去他博客找找,真心推荐)原本例题是POJ3667 Hotel  这个题目,是一个求连续空区间的情况,而hdoj这个题目是求给定区间单调连续的最大区间长度,两个题目思路很相似,将节点rt用sum[rt],lsum[rt],rsum[rt]来描述,分别表示rt对应区间即[l,r]内满足条件的区间的最大长度,从左边端点l开始满足条件的最大区间长度,从右边r开始向左的满足条件的最大区间长度。

    void PushUp(int rt,int m,int mid)//mid表示更新区间的中点,m表示长度
    {
        lsum[rt]=lsum[rt<<1];
        rsum[rt]=rsum[rt<<1|1];
        int t=1;
        if(A[mid]<A[mid+1])
        {
            if(lsum[rt]==(m-(m>>1)))
                lsum[rt]+=lsum[rt<<1|1];
            if(rsum[rt]==(m>>1))
                rsum[rt]+=rsum[rt<<1];
            t= rsum[rt<<1]+lsum[rt<<1|1];
        }
           sum[rt]=max(t,max(sum[rt<<1],sum[rt<<1|1]));
    }

    PushUp函数和query函数是关键  ,PushUp函数向上更新时,先将lsum[rt]用

    lsum[rt<<1]也就是左子区间左边开始的最大长度,如果这个区间长度刚好是l到mid之间的长度,说明区间已经穿过中点了,应该在加上右子区间lsum[rt<<1|1]这部分,类似的可以更新rsum[rt]。对于sum[rt]应该对应rsum[rt<<1]+lsum[rt<<1|1],sum[rt<<1],sum[rt<<1|1]三种情况中的最大值,因为满足条件的最长单调区间可以是左半部分,右半部分,或者贯穿中点。

    理解了这部分那么query函数可以按照类似的思路来写,但要注意的是对于贯穿中点的判断条件是A[mid]<A[mid+1],这样才能将两部分加起来。

    期间又一次犯二TLE了,原本是用C写的,max函数是用的宏定义,结果里面含有query函数,这样最终可能会两次调用query函数,不超时才怪,好在以前犯过一次,被基友发现了,改成algorithm里面的max就过了。哎,有个能debug基友就是好啊。hhha。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define N 100010
      5 #define lson l,m,rt<<1
      6 #define rson m+1,r,rt<<1|1
      7 
      8 using namespace std;
      9 int sum[N<<2],rsum[N<<2],lsum[N<<2],A[N];
     10 
     11 void PushUp(int rt,int m,int mid)
     12 {
     13     lsum[rt]=lsum[rt<<1];
     14     rsum[rt]=rsum[rt<<1|1];
     15     int t=1;
     16     if(A[mid]<A[mid+1])
     17     {
     18         if(lsum[rt]==(m-(m>>1)))
     19             lsum[rt]+=lsum[rt<<1|1];
     20         if(rsum[rt]==(m>>1))
     21             rsum[rt]+=rsum[rt<<1];
     22         t= rsum[rt<<1]+lsum[rt<<1|1];
     23     }
     24        sum[rt]=max(t,max(sum[rt<<1],sum[rt<<1|1]));
     25 }
     26 
     27 void build(int l,int r,int rt)
     28 {
     29     if(l==r)
     30     {
     31         sum[rt]=lsum[rt]=rsum[rt]=1;
     32         return;
     33     }
     34     int m=(l+r)>>1;
     35     build(lson);
     36     build(rson);
     37     PushUp(rt,r-l+1,m);
     38 }
     39 
     40 void update(int p,int l,int r,int rt)
     41 {
     42     if(l==r)
     43         return;
     44     int m=(l+r)>>1;
     45     if(p<=m)
     46         update(p,lson);
     47     else update(p,rson);
     48     PushUp(rt,r-l+1,m);
     49 }
     50 
     51 int query(int L,int R,int l,int r,int rt)
     52 {
     53     if(L<=l&&R>=r)
     54     {
     55         return sum[rt];
     56     }
     57     int m=(l+r)>>1;
     58     if(l==r)
     59         return 1;
     60     int ans=0;
     61     if(R<=m)
     62         ans=max(ans,query(L,R,lson));
     63     else  if(L>m)
     64         ans=max(ans,query(L,R,rson));
     65     else
     66     {
     67         ans=max(ans,query(L,R,lson));
     68         ans=max(ans,query(L,R,rson));
     69         int ll,rr;
     70         if(m-L+1>=rsum[rt<<1])
     71             ll=rsum[rt<<1];
     72         else ll=m-L+1;
     73         if(R-m>=lsum[rt<<1|1])
     74             rr=lsum[rt<<1|1];
     75         else rr=R-m;
     76         ans=max(ans,ll);
     77         ans=max(ans,rr);
     78         if(A[m+1]>A[m])
     79             ans=max(ans,ll+rr);
     80     }
     81     return ans;
     82 }
     83 
     84 int main(void)
     85 {
     86     int T;
     87     int n,m,a,b;
     88     char op[3];
     89     scanf("%d",&T);
     90     while(T--)
     91     {
     92         scanf("%d%d",&n,&m);
     93         for(int i=1; i<=n; i++)
     94             scanf("%d",A+i);
     95         build(1,n,1);
     96         while(m--)
     97         {
     98             scanf("%s%d%d",op,&a,&b);
     99             if(op[0]=='U')
    100             {
    101                 A[a+1]=b;
    102                 update(a+1,1,n,1);
    103             }
    104             else
    105             {
    106                 int ans=query(a+1,b+1,1,n,1);
    107                 printf("%d
    ",ans);
    108             }
    109         }
    110     }
    111     return 0;
    112 }
  • 相关阅读:
    121.买卖股票 求最大收益1 Best Time to Buy and Sell Stock
    409.求最长回文串的长度 LongestPalindrome
    202.快乐数 Happy Number
    459.(KMP)求字符串是否由模式重复构成 Repeated Substring Pattern
    326.是否为3的平方根 IsPowerOfThree
    231.是否为2的平方根 IsPowerOfTwo
    461.求两个数字转成二进制后的“汉明距离” Hamming Distance
    206.反转单链表 Reverse Linked List
    448. 数组中缺少的元素 Find All Numbers Disappeared in an Array
    常见表单元素处理
  • 原文地址:https://www.cnblogs.com/rootial/p/3250801.html
Copyright © 2011-2022 走看看