LCIS
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 #define maxn 100005 2 #include<algorithm> 3 #include<cstdio> 4 using namespace std; 5 6 struct Node 7 { 8 int lm,mm,rm;//以左端点开始的LCIS,整个区间的LCIS,以右端点结尾的LCIS 9 int left,right;//区间端点 10 int len() 11 { 12 return right-left+1; 13 } 14 } tree[maxn<<2]; 15 int N,M,val[maxn]; 16 17 void maintain(int id)//根据左右孩子信息来更新自己 18 { 19 int mid=(tree[id].left+tree[id].right)>>1; 20 if(val[mid]<val[mid+1])//左右子树存在合并的个数 21 { 22 tree[id].lm=tree[id<<1].lm+(tree[id<<1].lm==tree[id<<1].len()?tree[id<<1|1].lm:0); 23 tree[id].rm=tree[id<<1|1].rm+(tree[id<<1|1].rm==tree[id<<1|1].len()?tree[id<<1].rm:0); 24 tree[id].mm=max(max(tree[id].lm,tree[id].rm),max(tree[id<<1].mm,tree[id<<1|1].mm)); 25 tree[id].mm=max(tree[id].mm,tree[id<<1].rm+tree[id<<1|1].lm); 26 } 27 else 28 { 29 tree[id].lm=tree[id<<1].lm; 30 tree[id].rm=tree[id<<1|1].rm; 31 tree[id].mm=max(tree[id<<1].mm,tree[id<<1|1].mm); 32 } 33 } 34 void build(int id,int left,int right) 35 { 36 tree[id].left=left,tree[id].right=right; 37 if(left==right) 38 { 39 tree[id].lm=tree[id].mm=tree[id].rm=1; 40 return ; 41 } 42 if(right-left>0) 43 { 44 int mid=(left+right)>>1; 45 build(id<<1,left,mid); 46 build(id<<1|1,mid+1,right); 47 } 48 maintain(id);//根据左右孩子更新自己的区间信息LCIS 49 } 50 void update(int id,int left,int right,int va)//将区间[left,right]的值更新为va 51 { 52 if(tree[id].left==tree[id].right) 53 { 54 val[left]=va; 55 return; 56 } 57 int mid=(tree[id].left+tree[id].right)>>1; 58 if(right<=mid) update(id<<1,left,right,va); 59 else update(id<<1|1,left,right,va); 60 maintain(id); 61 } 62 int query(int id,int left,int right)//查找区间[left,right]内的LCIS 63 { 64 if(left==tree[id].left&&right==tree[id].right) return tree[id].mm; 65 int mid=(tree[id].left+tree[id].right)>>1; 66 if(right<=mid) return query(id<<1,left,right); 67 else if(left>mid) return query(id<<1|1,left,right); 68 else 69 { 70 int mm=max(query(id<<1,left,mid),query(id<<1|1,mid+1,right)); 71 if(val[mid]<val[mid+1]) 72 //tree[id<<1].rm是tree[id<<1]所代表区间的rm,可能会大于[left,mid]区间的总长度,同理另一边 73 mm=max(mm,min(mid-left+1,tree[id<<1].rm)+min(right-mid,tree[id<<1|1].lm)); 74 return mm; 75 } 76 } 77 78 int main() 79 { 80 //freopen("in.txt","r",stdin); 81 int cases,a,b,i; 82 char op; 83 scanf("%d",&cases); 84 while(cases--) 85 { 86 scanf("%d%d",&N,&M); 87 for(i=1; i<=N; i++) scanf("%d",&val[i]); 88 build(1,0,N); 89 for(i=0; i<M; i++) 90 { 91 scanf("%s%d%d",&op,&a,&b); 92 if(op=='Q') a++,b++,printf("%d\n",query(1,a,b)); 93 else a++,update(1,a,a,b); 94 } 95 } 96 return 0; 97 }