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 }

 

 

 

你可能感兴趣的:(HDU)