hdu 3308 LCIS

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

关键是如何建树的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[1000000];
struct node
{
	int l, r;int Llcis, Rlcis, lcis;int lnum, rnum;
}tree[4 * 10000001];
void pushup(int id)
{
	if (tree[2 * id].rnum >= tree[2 * id + 1].lnum)
	{
		tree[id].Llcis = tree[2 * id].Llcis, tree[id].Rlcis = tree[2 * id + 1].Rlcis;
		tree[id].lcis = max(tree[2*id].lcis, tree[2*id+1].lcis);
	}
	else
	{
		if ((tree[2 * id].r - tree[2 * id].l + 1) == tree[2 * id].Llcis)
			tree[id].Llcis = tree[2 * id].Llcis + tree[2 * id + 1].Llcis;
		else tree[id].Llcis = tree[2 * id].Llcis;
		if ((tree[2 * id + 1].r - tree[2 * id + 1].l + 1) == tree[2 * id + 1].Rlcis)
			tree[id].Rlcis = tree[2 * id + 1].Rlcis + tree[2 * id].Rlcis;
		else tree[id].Rlcis = tree[2 * id + 1].Rlcis;
		int t1 = tree[2 * id].Rlcis + tree[2 * id + 1].Llcis;
		int 	t2 = max(tree[id].Llcis, tree[id].Rlcis), t3 = max(tree[2 * id].lcis, tree[2 * id + 1].lcis);
		tree[id].lcis = max(t1, max(t3, t2));
	}
}
void build(int id, int l, int r)
{
	tree[id].l = l, tree[id].r = r;
	if (tree[id].l == tree[id].r)
	{
		tree[id].lnum = tree[id].rnum = a[l];
		tree[id].Llcis = tree[id].Rlcis = tree[id].lcis = 1;
		return;
	}
	int mid = (tree[id].l + tree[id].r) / 2;
	build(2 * id, l, mid);build(2 * id + 1, mid + 1, r);
	tree[id].lnum = tree[2 * id].lnum, tree[id].rnum = tree[2 * id + 1].rnum;
	pushup(id);
}
void update(int id, int pos, int val)
{
	if (tree[id].l == tree[id].r)
	{
		tree[id].lnum = tree[id].rnum = val;
		return;
	}
	int mid = (tree[id].l + tree[id].r) / 2;
	if (pos <= mid) update(2 * id, pos, val);
	else update(2 * id + 1, pos, val);
	tree[id].lnum = tree[2 * id].lnum, tree[id].rnum = tree[2 * id + 1].rnum;
	pushup(id);
}
int query(int id, int l, int r)
{
	if (tree[id].l == l&&tree[id].r == r)
		return tree[id].lcis;
	if (r <= (tree[id].l + tree[id].r) / 2) return query(2 * id, l, r);
	else if (l > (tree[id].l + tree[id].r) / 2) return query(2 * id + 1, l, r);
	else
	{
		int mid = (tree[id].l + tree[id].r) / 2, Lmax, Rmax;
		Lmax = query(2 * id, l, mid), Rmax = query(2 * id + 1, mid + 1, r);
		if (tree[2 * id].rnum >= tree[2 * id + 1].lnum) return max(Lmax, Rmax);
		else
		{
			int ans = 0;
			ans = min(mid - l + 1, tree[2 * id].Rlcis) + min(r - mid, tree[2 * id + 1].Llcis);
			return max(ans, max(Lmax, Rmax));
		}
	}
}
int main()
{
	int t, n, q, i, x, y;char c;
	cin >> t;
	while (t--)
	{

		cin >> n >> q;
		for (i = 1;i <= n;i++)
			cin >> a[i];
		build(1, 1, n);
		for (i = 0;i < q;i++)
		{
			cin >> c;
			if (c == 'Q')
			{
				cin >> x >> y;
				printf("%d\n", query(1, x + 1, y + 1));
			}
			if (c == 'U')
			{
				cin >> x >> y;
				update(1, x + 1, y);
			}
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值