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 }
  • 相关阅读:
    前端构建工具——Gulp
    jQuery事件命名空间
    浏览器类型鉴别那些事
    花式秀Mac——Mac快捷操作整理ing……
    解构jQuery之jQuery整体架构
    立即调用表达式
    iScroll小计
    JSONP原理及jQuery中的使用
    同源策略和跨域方法
    WebStrom、Sublime Text快捷键及使用技巧(补充ing...)
  • 原文地址:https://www.cnblogs.com/rootial/p/3250801.html
Copyright © 2011-2022 走看看