HDU 3308 LCIS
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
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<=10 5).
The next line has n integers(0<=val<=10 5).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=10 5)
OR
Q A B(0<=A<=B< n).
Each case starts with two integers n , m(0<n,m<=10 5).
The next line has n integers(0<=val<=10 5).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=10 5)
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 解题思路: 最长连续递增序列,设计成线段树的题目,这种题用线段树来做就好,线段树维护: llen[]区间左端点向右延伸的最大距离rlen[]区间右端点向左延伸的最大距离maxlen[]区间最大长度
一个正常的数组保存每一个位置的值
有几个地方要注意
1,区间合并的时候,判断左区间右端点小于右区间左端点即可合并,并处理llen和rlen的延伸
2,query的时候,注意当一个大区间被分为两部分的时候maxlen的值有可能就在中点m的位置
左右这时候需要拿出来处理一下#include<bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn = 100005 ; int maxlen[maxn<<2] ; int llen[maxn<<2] ; int rlen[maxn<<2] ; int arry[maxn] ; void pushup(int l,int r,int rt){ int m = (l+r)>>1 ; llen[rt] = llen[rt<<1] ; rlen[rt] = rlen[rt<<1|1] ; maxlen[rt] = max(maxlen[rt<<1],maxlen[rt<<1|1]) ; if(arry[m]<arry[m+1]){ maxlen[rt] = max(rlen[rt<<1]+llen[rt<<1|1] ,maxlen[rt]); if(llen[rt<<1] == m-l+1){ llen[rt] = llen[rt<<1]+llen[rt<<1|1] ; }if(rlen[rt<<1|1] == r-m){ rlen[rt] = rlen[rt<<1|1]+rlen[rt<<1] ; } } return ; } void build(int l,int r,int rt){ if(l==r){ scanf("%d",&arry[l]); maxlen[rt] = llen[rt] = rlen[rt] = 1 ; return ; } int m = (l+r)>>1 ; build(lson) ; build(rson) ; pushup(l,r,rt) ; //printf("rt = %d len = %d\n",rt,maxlen[rt]); } void update(int p,int s,int l,int r,int rt){ int m = (l+r)>>1 ; if(l==r){ arry[l] = s ; return ; } if(p<=m)update(p,s,lson) ; else update(p,s,rson) ; pushup(l,r,rt) ; } int query(int L,int R,int l,int r,int rt){ int ret = 1 ; if(L<=l&&r<=R){ return maxlen[rt] ; } int m = (l+r)>>1 ; if(arry[m]<arry[m+1])ret = max(ret,min(R,m+llen[rt<<1|1])-max(L,m+1-rlen[rt<<1])+1); if(L<=m)ret=max(ret,query(L,R,lson)) ; if(R>m)ret=max(ret,query(L,R,rson)) ; return ret ; } int n,m; int main(){ int T; //freopen("in.txt","r",stdin); //freopen("out2.txt","w",stdout); scanf("%d",&T); while(T--){ //memset(setv,0,sizeof(setv)) ; memset(arry,0,sizeof(arry)) ; memset(maxlen,0,sizeof(maxlen)) ; memset(llen,0,sizeof(llen)) ; memset(rlen,0,sizeof(rlen)) ; scanf("%d%d",&n,&m); build(1,n,1) ; //printf("masxn = %d\n",maxlen[1]); while(m--){ char op[3] ; int a,b; scanf("%s%d%d",op,&a,&b); if(op[0] == 'U'){ update(a+1,b,1,n,1) ; }else{ int ans = query(a+1,b+1,1,n,1) ; printf("%d\n",ans) ; } } } return 0; }