hdu3308LCIS(线段树区间合并)

http://acm.hdu.edu.cn/showproblem.php?pid=3308

注意两个地方 向上更新 和查找的时候

向上更新

1. 左儿子最右边的值 < 右儿子最左边的值

    lMax = (左儿子的lMax == 左儿子的len) ? 左儿子的len + 右儿子的lMax : 左儿子的lMax;
    rMax = (右儿子的rMax == 右儿子的len) ? 右儿子的len + 左儿子的rMax : 右儿子的rMax;
    Max  = MAX(左儿子的rMax + 右儿子的lMax, 左儿子的Max, 右儿子的Max, lMax, rMax);

2. 左儿子最右边的值 >= 右儿子最左边的值

    lMax = 左儿子的lMax;
    rMax = 右儿子的rMax;
    Max  = MAX(左儿子的Max, 右儿子的Max);

查找的时候 也分开来比较

 

View Code
  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<stdlib.h>
  5 #include<algorithm>
  6 using namespace std;
  7 #define N 100010
  8 int s[N<<2],mm[N<<2],lm[N<<2],rm[N<<2],len[N<<2];
  9 void update(int l,int r,int w)
 10 {
 11     int m = (l+r)>>1;
 12     if(s[m]<s[m+1])
 13     {
 14         lm[w] = (lm[w<<1]==len[w<<1])?(lm[w<<1]+lm[w<<1|1]):lm[w<<1];
 15         rm[w] = (rm[w<<1|1]==len[w<<1|1])?(rm[w<<1|1]+rm[w<<1]):rm[w<<1|1];
 16         mm[w] = max((rm[w<<1]+lm[w<<1|1]),mm[w<<1]);
 17         mm[w] = max(lm[w],mm[w]);
 18         mm[w] = max(rm[w],mm[w]);
 19         mm[w] = max(mm[w<<1|1],mm[w]);
 20     }
 21     else
 22     {
 23         lm[w] = lm[w<<1];
 24         rm[w] = rm[w<<1|1];
 25         mm[w] = max(mm[w<<1],mm[w<<1|1]);
 26     }
 27 }
 28 int search(int a,int b,int l,int r,int w)
 29 {
 30     if(a<=l&&b>=r)
 31     {
 32         return mm[w];
 33     }
 34     int m = (l+r)>>1;
 35     if(b<=m)
 36     return search(a,b,l,m,w<<1);
 37     if(a>m)
 38     return search(a,b,m+1,r,w<<1|1);
 39     int len,ren,ans ;
 40     len = search(a,b,l,m,w<<1);
 41     ren = search(a,b,m+1,r,w<<1|1);
 42     ans = max(len,ren);
 43     if(s[m]<s[m+1])
 44     {
 45         int re;
 46         re=min(rm[w<<1],m-a+1)+min(lm[w<<1|1],b-m);
 47         ans=max(re,ans);
 48     }
 49     return ans;
 50 }
 51 void build(int l,int r,int w)
 52 {
 53     len[w] = (r-l+1);
 54     if(l==r)
 55     {
 56         mm[w] = 1;
 57         lm[w] = 1;
 58         rm[w] = 1;
 59         return ;
 60     }
 61     int m = (l+r)>>1;
 62     build(l,m,w<<1);
 63     build(m+1,r,w<<1|1);
 64     update(l,r,w);
 65 }
 66 void change(int p,int d,int l,int r,int w)
 67 {
 68     if(l==r&&l==p)
 69     {
 70         return ;
 71     }
 72     int m = (l+r)>>1;
 73     if(p<=m)
 74     change(p,d,l,m,w<<1);
 75     else
 76     change(p,d,m+1,r,w<<1|1);
 77     update(l,r,w);
 78 }
 79 int main()
 80 {
 81     int i,j,k,n,m,t,a,b;
 82     char c;
 83     cin>>t;
 84     while(t--)
 85     {
 86         cin>>n>>m;
 87         for(i = 1; i <= n ; i++)
 88         scanf("%d",&s[i]);
 89         build(1,n,1);
 90         while(m--)
 91         {
 92             cin>>c>>a>>b;
 93             if(c=='U')
 94             {
 95                 s[a+1] = b;
 96                 change(a+1,b,1,n,1);
 97             }
 98             else
 99             {
100                 cout<<search(a+1,b+1,1,n,1)<<endl;
101             }
102         }
103     }
104     return 0;
105 }

 

 

 

posted @ 2013-03-22 18:01  _雨  阅读(642)  评论(0编辑  收藏  举报