线段树 HDU 3308 LCIS
2012-08-30 22:07
435 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308
代码风格:http://www.notonlysuccess.com/index.php/segment-tree-complete/
题目大意:求连续最长上升数字的个数
算法:线段树 区间合并
思路:如果分配到左子树的最右边的数 小于 右子树的最左边的那个数,那么合并区间
代码风格:http://www.notonlysuccess.com/index.php/segment-tree-complete/
题目大意:求连续最长上升数字的个数
算法:线段树 区间合并
思路:如果分配到左子树的最右边的数 小于 右子树的最左边的那个数,那么合并区间
#include"cstdio" #include"cstring" #include"iostream" #include"algorithm" using namespace std; #define lson l, m, rt << 1 #define rson m+1, r, rt << 1 | 1 #define mid int m = (l+r) >> 1 int c[123456 << 2], rsum[898998], lsum[898989], msum[787878]; int max(int a, int b) { return a > b ? a : b; } void PushUp(int l, int r, int rt, int m) { //cout << c[l] << c[r] << endl; if(c[l] < c[r]) { lsum[rt] = lsum[rt << 1]; rsum[rt] = rsum[rt << 1 | 1]; if(lsum[rt] == m - (m >> 1)) lsum[rt] += lsum[rt << 1 |1 ]; if(rsum[rt] == m >> 1) rsum[rt] += rsum[rt << 1]; msum[rt] = max(msum[rt << 1], max(msum[rt << 1 | 1], lsum[rt << 1 | 1]+ rsum[rt << 1])); } else { lsum[rt] = lsum[rt << 1]; rsum[rt] = rsum[rt << 1 | 1]; msum[rt] = max(msum[rt << 1], msum[rt << 1 | 1]); } //printf("lsum[%d] = %d\n", rt , lsum[rt]); } void build(int l, int r, int rt) { if(l == r) { lsum[rt] = msum[rt] = rsum[rt] = 1; return ; } mid ; build(lson); build(rson); PushUp(m, m+1, rt, r-l+1); } void update(int d, int k, int l, int r, int rt) { if( l == r) { c[l] = k; return ; } mid ; if( d <= m) update(d, k, lson); else update(d, k, rson); PushUp(m, m+1, rt, r-l+1); } int min(int a, int b) { return a < b ? a : b; } int query(int L, int R, int l, int r, int rt) { if(L <=l && r <= R) { return msum[rt]; } mid ; if(L > m) { return query(L, R, rson); } else if( R <= m) { return query(L, R, lson); } else { int ll = query(L, R, lson); int rr = query(L, R, rson); int mm = max(ll , rr); if(c[m] < c[m+1]) { mm = max(mm, min(rsum[rt << 1], m + 1 - L) + min( lsum[rt << 1 | 1], R - m) ); } return mm ; } } int main() { int n, m, T; cin >> T; while(T --) { int i; scanf("%d%d", &n, &m); for( i = 0; i < n; i++) { scanf("%d", &c[i]); } build(0, n-1, 1); while(m --) { char op[2]; int a, b; scanf("%s%d%d", op, &a, &b); if(op[0] =='Q') { printf("%d\n", query(a, b, 0, n-1, 1)); } else { update(a, b, 0, n-1, 1); } } } return 0; }
相关文章推荐
- HDU - 3308 - LCIS (线段树 - 区间合并)
- 【线段树求LCIS】HDU 3308
- hdu 3308 线段树区间 LCIS
- hdu-3308-LCIS 线段树
- HDU 3308 LCIS 线段树 区间合并 入门题
- HDU 3308 LCIS 线段树维护区间lcs
- 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(线段树区间合并)
- HDU 3308 LCIS(线段树)