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].
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).
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 }