当前位置: 首页 > 工具软件 > Pushup > 使用案例 >

【hdu3308 LCIS】【线段树】【pushup】【最长连续上升序列】

郑宜民
2023-12-01

【链接】

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

【题意】

给你n个数,m个操作。

操作有两种:

1.U x y 将数组第x位变为y  

2. Q x y 问数组第x位到第y位连续最长子序列的长度

【思路】

满足区间可加。

线段树维护信息:区间最长连续上升序列,前缀最长上升序列,后缀最长上升序列。

pushup(p)修改的时候注意判断条件

【代码】

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 6;
int a[maxn];

struct node {
	int l, r, sub, lc, rc;
}t[maxn<<2];

inline void pushup(int p) {//本题核心,pushup的修改
	int mid = (t[p].l + t[p].r )>> 1;
	t[p].lc = t[p << 1].lc; t[p].rc = t[p << 1 | 1].rc;
	t[p].sub = max(t[p << 1].sub, t[p << 1 | 1].sub);
	if (a[mid] < a[mid + 1]) {
		if (t[p].lc == mid - t[p].l + 1)t[p].lc += t[p << 1 | 1].lc;
		if (t[p].rc == t[p].r - mid)t[p].rc += t[p << 1].rc;
		t[p].sub = max(t[p << 1].rc + t[p << 1 | 1].lc, t[p].sub);
	}
}

void build(int p, int l, int r) {
	t[p].l = l; t[p].r = r;
	if (l == r) { t[p].lc = t[p].rc = t[p].sub = 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 v) {//单点修改
	if (t[p].l == t[p].r) {
		return;
	}
	int mid = (t[p].l + t[p].r) >> 1;
	if (pos <= mid)update(p << 1, pos, v);
	else update(p << 1 | 1, pos, v);
	pushup(p);
}

int query(int p, int l, int r) {//查询区间[t[p].l,t[p],r]的最长连续上升子序列,核心
	if (l <= t[p].l&&r >= t[p].r) {
		return t[p].sub;
	}
	int mid = (t[p].l + t[p].r) >> 1;
	if (r <= mid)return query(p << 1, l, r);
	if (l > mid)return query(p << 1 | 1, l, r);//一共三种可能:左区间,右区间或者横跨左右两个区间
	int t1 = query(p << 1, l, r);
	int t2 = query(p << 1 | 1, l, r);
	int ans = max(t1, t2);
	if (a[mid] < a[mid + 1]) {
		ans = max(ans, min(t[p << 1].rc,mid-l+1) + min(t[p << 1 | 1].lc,r-mid));
	}
	return ans;
}

int main() {
	int T;scanf("%d", &T); 
	while (T--) {
		int n, m;
		scanf("%d%d", &n, &m);
		for (int i = 1; i <= n; i++)scanf("%d", &a[i]);
		build(1, 1, n);
		while (m--) {
			char op[5];
			int x, y;
			scanf("%s%d%d", op, &x, &y);x++;
			if (op[0] == 'U') {
				a[x] = y;
				update(1, x, y);
			}
			else {
				y++;
				printf("%d\n", query(1, x, y));
			}
		}
	}
	scanf("%d", &T);
}

 

 类似资料: