HDU 3308 LCIS(区间合并 + 单点更新)
2015-08-12 11:12
519 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308
题意:给定n个数。2种操作。
更新第a个数为b。
查询区间[a,b]的最长连续上升子序列。
思路:裸的区间合并。每个结点存
从区间左端点开始的最长连续上升子序列的长度lm。
以区间右端点结束的最长连续上升子序列的长度rm。
区间的最长连续上升子序列的长度mx。
区间左端点的数值la。
区间右端点的数值ra。
代码:
题意:给定n个数。2种操作。
更新第a个数为b。
查询区间[a,b]的最长连续上升子序列。
思路:裸的区间合并。每个结点存
从区间左端点开始的最长连续上升子序列的长度lm。
以区间右端点结束的最长连续上升子序列的长度rm。
区间的最长连续上升子序列的长度mx。
区间左端点的数值la。
区间右端点的数值ra。
代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #include <string> using namespace std; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 const int N = 5e5 + 10; const int INF = 0x7f7f7f7f; struct Node { int lm; int rm; int mx; int la; int ra; Node() {} Node(int a, int b, int c, int d, int e) { lm = a; rm = b; mx = c; la = d; ra = e; } }; Node node[N << 2]; void pushup(int rt, int l, int r) { int m = (l + r) >> 1; node[rt].mx = max(node[rt << 1].mx, node[rt << 1 | 1].mx); if (node[rt << 1].ra < node[rt << 1 | 1].la) node[rt].mx = max(node[rt].mx, node[rt << 1].rm + node[rt << 1 | 1].lm); if (node[rt << 1].lm == m - l + 1 && node[rt << 1].ra < node[rt << 1 | 1].la) node[rt].lm = node[rt << 1].lm + node[rt << 1 | 1].lm; else node[rt].lm = node[rt << 1].lm; if (node[rt << 1 | 1].rm == r - m && node[rt << 1].ra < node[rt << 1 | 1].la) node[rt].rm = node[rt << 1 | 1].rm + node[rt << 1].rm; else node[rt].rm = node[rt << 1 | 1].rm; node[rt].la = node[rt << 1].la; node[rt].ra = node[rt << 1 | 1].ra; } void build(int l, int r, int rt) { if (l == r) { int x; scanf("%d", &x); node[rt].la = node[rt].ra = x; node[rt].lm = node[rt].rm = node[rt].mx = 1; return ; } int m = (l + r) >> 1; build(lson); build(rson); pushup(rt, l, r); } void update(int x, int v, int l, int r, int rt) { if (l == r) { node[rt].la = node[rt].ra = v; return ; } int m = (l + r) >> 1; if (x <= m) update(x, v, lson); else update(x, v, rson); pushup(rt, l, r); } Node query(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) { return node[rt]; } int m = (l + r) >> 1; Node ql = Node(0, 0, 0, 0, 0), qr = Node(0, 0, 0, 0, 0), res; if (L <= m) ql = query(L, R, lson); if (R > m) qr = query(L, R, rson); res.mx = max(ql.mx, qr.mx); if (ql.ra < qr.la) res.mx = max(res.mx, ql.rm + qr.lm); if (ql.lm == m - l + 1 && ql.ra < qr.la) res.lm = ql.lm + qr.lm; else res.lm = ql.lm; if (qr.rm == r - m && ql.ra < qr.la) res.rm = qr.rm + ql.rm; else res.rm = qr.rm; res.la = ql.la; res.ra = qr.ra; return res; } int main() { int t_case; scanf("%d", &t_case); for (int i_case = 1; i_case <= t_case; i_case++) { int n, m; scanf("%d%d", &n, &m); build(1, n, 1); for (int i_q = 1; i_q <= m; i_q++) { char op[3]; int a, b; scanf("%s%d%d", op, &a, &b); if (op[0] == 'Q') { a++; b++; Node res = query(a, b, 1, n, 1); printf("%d\n", res.mx); } else { a++; update(a, b, 1, n, 1); } } } return 0; }
相关文章推荐
- 下拉匹配功能
- 22次会战,你们省有几个?
- 如何解决cellIndex在IE下兼容性问题
- iOS中的NSValue
- asp.net中关于《%=》《%#》《%》 的用法——(转帖)
- LeetCode:Binary Tree Preorder Traversal(二叉树的先序遍历)
- N的阶乘(N!)中的末尾有多少个0?
- CocoaPods安装和使用教程
- DWZ富客户端框架 api
- 合并表记录
- 备份
- iOS开发 使用GCD实现多任务
- KMP算法的next、next value数组代码实现及POJ3461
- Java安全通信:HTTPS与SSL
- CoreData之条件查询 contains
- LeetCode题解:Contains Duplicate II
- SASS语法学习
- 域名解析
- iOS中的NSArraySort(^块语法)
- CoreData之条件查询 contains