hdu 3308 LCIS

LCIS

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2640    Accepted Submission(s): 1143

Problem Description
Given n integers.
You have two operations:
U A B: replace the Ath number by B. (index counting from 0)
Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b].
 
Input
T in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=105).
The next line has n integers(0<=val<=105).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=105)
OR
Q A B(0<=A<=B< n).
 
Output
For each Q, output the answer.
 
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 /**
  2 这是一道经典的线段树题目。
  3 有分治的思想在里面
  4 求解区间[L , R]最长递增子序列的长度。
  5 
  6 对于一个线段树的区间
  7 我们需要保存左端点的值,右端点的值,
  8 以及分别包含左右端点所能达到的最长递增子序列的长度
  9 lmaxn ,rmaxn;还要有一个保存区间最彻底子序列的值maxn。
 10 
 11 **/
 12 #include<iostream>
 13 #include<stdio.h>
 14 #include<cstring>
 15 #include<cstdlib>
 16 using namespace std;
 17 
 18 struct node
 19 {
 20     int l,r,len;
 21     int lnum,rnum,lmaxn,rmaxn,maxn;
 22 }f[100002*4];
 23 int date;
 24 
 25 /**
 26 向上更新函数。
 27 **/
 28 void up(int n,int LChild,int RChild)
 29 {
 30     f[n].lnum = f[LChild].lnum;
 31     f[n].rnum = f[RChild].rnum;
 32 
 33     f[n].lmaxn = (f[LChild].lmaxn==f[LChild].len && f[LChild].rnum<f[RChild].lnum)?
 34                           f[LChild].lmaxn+f[RChild].lmaxn:f[LChild].lmaxn;
 35     f[n].rmaxn = (f[RChild].rmaxn==f[RChild].len && f[LChild].rnum<f[RChild].lnum)?
 36                           f[RChild].rmaxn+f[LChild].rmaxn:f[RChild].rmaxn;
 37 
 38     f[n].maxn = max(f[LChild].maxn,f[RChild].maxn);
 39     if(f[LChild].rnum<f[RChild].lnum)
 40         f[n].maxn = max(f[n].maxn,f[LChild].rmaxn+f[RChild].lmaxn);
 41   //  f[n].maxn = max(f[n].maxn,max(f[n].lmaxn,f[n].rmaxn));
 42 /**
 43 这里可以不用这句  f[n].maxn = max(f[n].maxn,max(f[n].lmaxn,f[n].rmaxn));
 44 思考吧。
 45 **/
 46 }
 47 void build(int l,int r,int n)
 48 {
 49     int mid=(l+r)/2;
 50     f[n].l = l;
 51     f[n].r = r;
 52     f[n].len = f[n].r-f[n].l+1;
 53     f[n].lnum=f[n].rnum=0;
 54     f[n].lmaxn=f[n].rmaxn=f[n].maxn=0;
 55     if(l==r)
 56     {
 57         scanf("%d",&date);
 58         f[n].lnum=f[n].rnum=date;
 59         f[n].lmaxn=f[n].rmaxn=f[n].maxn=1;
 60         return;
 61     }
 62     build(l,mid,n*2);
 63     build(mid+1,r,n*2+1);
 64     up(n,n*2,n*2+1);
 65 }
 66 void update(int wz,int num,int n)
 67 {
 68     int mid=(f[n].l + f[n].r)/2;
 69     if(f[n].l == wz && f[n].r == wz)
 70     {
 71         f[n].lnum=f[n].rnum=num;
 72         f[n].lmaxn=f[n].rmaxn=f[n].maxn=1;
 73         return;
 74     }
 75     if(mid>=wz) update(wz,num,n*2);
 76     else if(mid<wz) update(wz,num,n*2+1);
 77     up(n,n*2,n*2+1);
 78 }
 79 
 80 int query(int l,int r,int n)
 81 {
 82     int mid=(f[n].l + f[n].r)/2;
 83     if(f[n].l == l && f[n].r == r)
 84     {
 85         return f[n].maxn;
 86     }
 87     if(mid>=r) return query(l,r,n*2);
 88     else if(mid<l) return query(l,r,n*2+1);
 89     else {
 90             /**
 91             这里也需要注意。
 92             **/
 93             int lmaxn = query(l,mid,n*2); //查询左边最大值
 94             int rmaxn =query(mid+1,r,n*2+1);//查询右边最大值
 95             int maxn = 0;
 96             if(f[n*2].rnum<f[n*2+1].lnum) //这个也需要讨论。
 97                 maxn = min(mid-l+1,f[n*2].rmaxn)+min(r-mid,f[n*2+1].lmaxn);
 98             maxn = max(maxn,max(lmaxn,rmaxn));
 99             return maxn;
100     }
101 }
102 int main()
103 {
104     int T,n,m;
105     int l,r,wz,num;
106     char a[10];
107     scanf("%d",&T);
108     while(T--)
109     {
110         scanf("%d%d",&n,&m);
111         build(1,n,1);
112         while(m--)
113         {
114             scanf("%s",a);
115             if(a[0] == 'Q')
116             {
117                 scanf("%d%d",&l,&r);
118                 l++,r++;
119                 printf("%d\n",query(l,r,1));
120             }
121             else if(a[0]=='U')
122             {
123                 scanf("%d%d",&wz,&num);
124                 wz++;
125                 update(wz,num,1);
126             }
127         }
128     }
129     return 0;
130 }

 

 

 

 

posted @ 2013-05-02 19:34  芷水  阅读(142)  评论(0编辑  收藏  举报