hdu 3308 线段树

题目大意:给n个数,两种操作1:U  a b   更新第a个为b (从0开始)
2: Q    a ,b  查询 a,b之间LCIS(最长连续递增子序列)的长度。

Sample Input
1
10 10
7 7 3 3 5 9 9 8 1 8
Q 6 6
U 3 4
Q 0 1
Q 0 5
Q 4 7
Q 3 5
Q 0 2
Q 4 6
U 6 10
Q 0 9
Sample Output

1
1
4
2
3
1
2
5

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <algorithm>
  4 #include <iostream>
  5 #define lson l,m,rt<<1
  6 #define rson m+1,r,rt<<1|1
  7 #define maxn  100005
  8 using namespace std;
  9 
 10 int mlen[maxn<<2],lmlen[maxn<<2],rmlen[maxn<<2];
 11 int num[maxn];
 12 
 13 void pushup(int rt,int l,int r)
 14 {
 15     lmlen[rt]=lmlen[rt<<1];
 16     rmlen[rt]=rmlen[rt<<1|1];
 17     mlen[rt]=max(mlen[rt<<1],mlen[rt<<1|1]);
 18     int mid=(l+r)>>1;
 19     int m=(r-l)+1;
 20     if(num[mid]<num[mid+1]) //左区间的右值小于右区间的左值可以合并
 21     {
 22         if(lmlen[rt]==m-(m>>1)) lmlen[rt]+=lmlen[rt<<1|1];
 23         if(rmlen[rt]==(m>>1)) rmlen[rt]+=rmlen[rt<<1];
 24         mlen[rt]=max(mlen[rt],lmlen[rt<<1|1]+rmlen[rt<<1]);
 25     }
 26 }
 27 void build(int l,int r,int rt)
 28 {
 29     if(l==r)
 30     {
 31         mlen[rt]=lmlen[rt]=rmlen[rt]=1;
 32         return ;
 33     }
 34     int m=(l+r)>>1;
 35     build(lson);
 36     build(rson);
 37     pushup(rt,l,r);
 38 }
 39 void  update(int a,int l,int r,int rt)
 40 {
 41     if(l==r)
 42     {
 43         return;
 44     }
 45     int m=(l+r)>>1;
 46     if(a<=m) update(a,lson);
 47     else update(a,rson);
 48     pushup(rt,l,r);
 49 }
 50 
 51 int query(int L,int R,int l,int r,int rt)
 52 {
 53     //printf("%d %d %d %d %d\n",L,R,l,r,rt);
 54     if(L<=l&&r<=R)
 55     {
 56         return mlen[rt];
 57     }
 58     int m=(l+r)>>1;
 59     if(R<=m) return query(L,R,lson); //与一般不同,不能是子集,只能全部属于才能直接查询子区间 返回子区间的mlen
 60     if(L>m) return query(L,R,rson);  //否则是确认儿子区间是否能合并,并在三者之间取最大值
 61 
 62     int ta,tb;
 63     ta=query(L,R,lson);
 64     tb=query(L,R,rson);
 65     int ans;
 66     ans=max(ta,tb);
 67     if(num[m]<num[m+1])  //同上
 68     {
 69         int temp;
 70         temp=min(rmlen[rt<<1],m-L+1)+min(lmlen[rt<<1|1],R-m);
 71         ans=max(temp,ans);
 72     }
 73     return ans;
 74 }
 75 
 76 int main()
 77 {
 78     int T,n,m;
 79     int i,j;
 80     char f[2];
 81     int a,b;
 82     #ifndef ONLINE_JUDGE
 83     freopen("1.in","r",stdin);
 84     #endif
 85     scanf("%d",&T);
 86     for(i=0;i<T;i++)
 87     {
 88         scanf("%d %d",&n,&m);
 89         for(j=1;j<=n;j++)
 90            scanf("%d",&num[j]);
 91         build(1,n,1);
 92         while(m--)
 93         {
 94             scanf("%s",&f);
 95             if(f[0]=='U')
 96             {
 97                 scanf("%d %d",&a,&b);
 98                 a++;
 99                 num[a]=b;
100                 update(a,1,n,1);
101             }
102             else
103             {
104                 scanf("%d %d",&a,&b);
105                 a++,b++;
106                 printf("%d\n",query(a,b,1,n,1));
107             }
108         }
109     }
110     return 0;
111 }

 

posted @ 2015-04-21 09:39  miao_a_miao  阅读(134)  评论(0编辑  收藏  举报