HDU3308 LCIS【线段树 区间合并】

LCIS

http://acm.hdu.edu.cn/showproblem.php?pid=3308

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


 

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 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

Author

shǎ崽

 

Source

HDOJ Monthly Contest – 2010.02.06

 

题意

给出n个数,有两种操作一种为(U x y)将x点的值改为y,另一种为(Q x y)求区间[x,y]最长连续递增序列长度

题解

sum[i]表示i控制的区间中的最长严格递增子序列长度
lsum[i]表示以i为前缀的最长严格递增子序列长度
rsum[i]表示以i为后缀的最长严格递增子序列长度 

 

查找在[L,R]中以i为前缀或后缀的最大严格递增子序列是由如下语句实现

min(rsum[rt<<1],m-L+1)+min(lsum[rt<<1|1],R-m)

开始时自己写了函数查询,却发现过不了,也不知道查询函数错在哪。也就只能用上面的语句了。

//调用此函数的前提是l在区间[L,R]内 
//查询以l为起点向后,终点在[L,R]区间内的最长严格递增子序列的长度 
int lquery(int L,int R,int l,int r,int rt)
{
	if(l+lsum[rt]-1<=R) return lsum[rt];
	int m=(l+r)>>1;
	if(m>=R) return lquery(L,R,ls);
	int len=lsum[rt<<1];
	if(len=m-l+1&&a[m]=L) return rsum[rt];
	int m=(l+r)>>1;
	if(m

C++代码

#include
#include

using namespace std;

#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1

const int N=100100;

//sum[i]表示i控制的区间中的最长严格递增子序列长度
//lsum[i]表示以i为前缀的最长严格递增子序列长度
//rsum[i]表示以i为后缀的最长严格递增子序列长度 
int sum[N<<2],lsum[N<<2],rsum[N<<2],a[N];

void pushup(int l,int r,int rt)
{
	int m=(l+r)>>1;
	
	sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
	if(a[m]>1;
	build(ls);
	build(rs);
	pushup(l,r,rt);
}

void update(int L,int C,int l,int r,int rt)
{
	if(l==r)
	{
		a[l]=C;
		return;
	}
	int m=(l+r)>>1;
	if(L<=m)
	  update(L,C,ls);
	else
	  update(L,C,rs);
	pushup(l,r,rt);
}

int query(int L,int R,int l,int r,int rt)
{
	if(L<=l&&r<=R) return sum[rt];
	int m=(l+r)>>1;
	if(R<=m) return query(L,R,ls);
	if(L>m) return query(L,R,rs);
	int len=max(query(L,R,ls),query(L,R,rs));
	int tmp;
	if(a[m]

 

你可能感兴趣的:(数据结构)