hdu3308----LCIS

LCIS

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


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

Author
shǎ崽
 

Source
HDOJ Monthly Contest – 2010.02.06
 

Recommend
wxl   |   We have carefully selected several similar problems for you:   1698  3397  1542  1828  2871 
 

线段树区间合并,简单题

/*************************************************************************
    > File Name: seg_7.cpp
    > Author: ALex
    > Mail: [email protected] 
    > Created Time: 2015年01月09日 星期五 19时15分18秒
 ************************************************************************/

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1e5 + 10;

int num[N];
struct node
{
	int l, r;
	int lis;
	int l_lis, r_lis;
}tree[N << 2];

void pushup(int p)
{
	tree[p].l_lis = tree[p << 1].l_lis;
	tree[p].r_lis = tree[p << 1 | 1].r_lis;
	if (tree[p << 1].l_lis == tree[p << 1].r - tree[p << 1].l + 1 && num[tree[p << 1].r] < num[tree[p << 1 | 1].l])
	{
		tree[p].l_lis += tree[p << 1 | 1].l_lis;
	}
	if (tree[p << 1 | 1].r_lis == tree[p << 1 | 1].r - tree[p << 1 | 1].l + 1 && num[tree[p << 1].r] < num[tree[p << 1 | 1].l])
	{
		tree[p].r_lis += tree[p << 1].r_lis;
	}
	int m = 0;
	if (num[tree[p << 1].r] < num[tree[p << 1 | 1].l])
	{
		m = tree[p << 1].r_lis + tree[p << 1 | 1].l_lis;
	}
	tree[p].lis = max(m, max(tree[p << 1].lis, tree[p << 1 | 1].lis));
}

void build (int p, int l, int r)
{
	tree[p].l = l;
	tree[p].r = r;
	if (l == r)
	{
		tree[p].lis = tree[p].l_lis = tree[p].r_lis = 1;
		return;
	}
	int mid = (l + r) >> 1;
	build (p << 1, l, mid);
	build (p << 1 | 1, mid + 1, r);
	pushup(p);
}

void update (int p, int pos, int val)
{
	if (tree[p].l == tree[p].r)
	{
		num[tree[p].l] = val;
		return;
	}
	int mid = (tree[p].l + tree[p].r) >> 1;
	if (pos <= mid)
	{
		update (p << 1, pos, val);
	}
	else if (pos > mid)
	{
		update (p << 1 | 1, pos, val);
	}
	pushup(p);
}

int query (int p, int l, int r)
{
	if (tree[p].l == l && tree[p].r == r)
	{
		return tree[p].lis;
	}
	int mid = (tree[p].l + tree[p].r) >> 1;
	if (r <= mid)
	{
		return query (p << 1, l, r);
	}
	else if (l > mid)
	{
		return query (p << 1 | 1, l, r);
	}
	else
	{
		if (num[tree[p << 1].r] < num[tree[p << 1 | 1].l])
		{
			int l1, l2;
			if (tree[p << 1].r_lis > (mid - l + 1)) 
			{
				l1 = mid - l + 1;
			}
			else
			{
				l1 = tree[p << 1].r_lis;
			}
			if (tree[p << 1 | 1].l_lis > (r - mid))
			{
				l2 = r - mid;
			}
			else
			{
				l2 = tree[p << 1 | 1].l_lis;
			}
			return max(l1 + l2, max(query (p << 1, l, mid), query (p << 1 | 1, mid + 1, r)));
		}
		return max(query (p << 1, l, mid), query (p << 1 | 1, mid + 1, r));
	}
}

int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		int n, m;
		char str[4];
		int x, y;
		scanf("%d%d", &n, &m);
		for (int i = 0; i < n; ++i)
		{
			scanf("%d", &num[i]);
		}
		build (1, 0, n - 1);
		while (m--)
		{
			scanf ("%s%d%d", str, &x, &y);
			if (str[0] == 'Q')
			{
				printf("%d\n", query (1, x, y));
			}
			else if (str[0] == 'U')
			{
				update (1, x, y);
			}
		}
	}
	return 0;
}


你可能感兴趣的:(线段树)