HDU 3308 LCIS(线段树)
2014-05-02 17:11
316 查看
[align=left]Problem Description[/align]
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].
[align=left]Input[/align]
T in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=105).
The next line has n integers(0<=val<=105).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=105)
OR
Q A B(0<=A<=B< n).
[align=left]Output[/align]
For each Q, output the answer.
题目大意:给n个数,动态地修改某个数的值,或者查询一段区间的LCIS(最长连续上升子序列,坑爹的标题……)。
思路:线段树,每个点维护一个区间的从左边开始的最长的LCIS,从右边开始的最长的LCIS,这个区间最大的LCIS。然后随便搞搞就能过了……
代码(593MS):
View Code
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].
[align=left]Input[/align]
T in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=105).
The next line has n integers(0<=val<=105).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=105)
OR
Q A B(0<=A<=B< n).
[align=left]Output[/align]
For each Q, output the answer.
题目大意:给n个数,动态地修改某个数的值,或者查询一段区间的LCIS(最长连续上升子序列,坑爹的标题……)。
思路:线段树,每个点维护一个区间的从左边开始的最长的LCIS,从右边开始的最长的LCIS,这个区间最大的LCIS。然后随便搞搞就能过了……
代码(593MS):
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 100010 << 2; int lmax[MAXN], rmax[MAXN], mmax[MAXN]; int a[MAXN], n, m, T; void update(int x, int l, int r, int pos, int val) { if(pos <= l && r <= pos) { a[pos] = val; } else { int ll = x << 1, rr = ll | 1, mid = (l + r) >> 1; if(pos <= mid) update(ll, l, mid, pos, val); if(mid < pos) update(rr, mid + 1, r, pos, val); if(a[mid] < a[mid + 1]) { lmax[x] = lmax[ll] + (lmax[ll] == mid - l + 1) * lmax[rr]; rmax[x] = rmax[rr] + (rmax[rr] == r - mid) * rmax[ll]; mmax[x] = max(rmax[ll] + lmax[rr], max(mmax[ll], mmax[rr])); } else { lmax[x] = lmax[ll]; rmax[x] = rmax[rr]; mmax[x] = max(mmax[ll], mmax[rr]); } } } int query(int x, int l, int r, int aa, int bb) { if(aa <= l && r <= bb) { return mmax[x]; } else { int ll = x << 1, rr = ll | 1, mid = (l + r) >> 1; int ans = 0; if(aa <= mid) ans = max(ans, query(ll, l, mid, aa, bb)); if(mid < bb) ans = max(ans, query(rr, mid + 1, r, aa, bb)); if(a[mid] < a[mid + 1]) ans = max(ans, min(rmax[ll], mid - aa + 1) + min(lmax[rr], bb - mid)); return ans; } } void build(int x, int l, int r) { if(l == r) { lmax[x] = rmax[x] = mmax[x] = 1; } else { int ll = x << 1, rr = ll | 1, mid = (l + r) >> 1; build(ll, l, mid); build(rr, mid + 1, r); if(a[mid] < a[mid + 1]) { lmax[x] = lmax[ll] + (lmax[ll] == mid - l + 1) * lmax[rr]; rmax[x] = rmax[rr] + (rmax[rr] == r - mid) * rmax[ll]; mmax[x] = max(rmax[ll] + lmax[rr], max(mmax[ll], mmax[rr])); } else { lmax[x] = lmax[ll]; rmax[x] = rmax[rr]; mmax[x] = max(mmax[ll], mmax[rr]); } } } int main() { scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for(int i = 0; i < n; ++i) scanf("%d", &a[i]); build(1, 0, n - 1); while(m--) { char c; int a, b; scanf(" %c%d%d", &c, &a, &b); if(c == 'Q') printf("%d\n", query(1, 0, n - 1, a, b)); else update(1, 0, n - 1, a, b); } } }
View Code
相关文章推荐
- HDU 3308 LCIS(线段树区间合并)
- HDU 3308 LCIS(线段树)
- HDU 3308 LCIS (线段树区间合并)
- HDU 3308 - LCIS(线段树+区间合并)
- HDU - 3308 LCIS(线段树)
- hdu 3308 LCIS(线段树)
- HDU 3308 LCIS (线段树~)
- HDU 3308 LCIS(线段树区间合并)
- HDU 3308 LCIS(最长连续上升子序列)(线段树区间合并)
- HDU 3308 LCIS(线段树区间合并 单点更新)
- HDU 3308 LCIS (线段树)
- HDU 3308 LCIS(线段树单点更新区间合并)
- HDU 3308 LCIS 线段树 PushUp应用
- HDU 3308——LCIS(线段树,区间合并,最长连续递增子序列)
- hdu 3308 LCIS(线段树区间合并)
- HDU 3308 LCIS 线段树
- HDU 3308 LCIS 最长连续递增序列+数据结构+线段树+单点更新
- HDU 3308 LCIS 线段树
- (简单) HDU 3308 LCIS,线段树+区间合并。
- hdu 3308 LCIS(线段树)