hdu 3308 LCIS(单点更新+区间合并)
2013-10-09 22:04
369 查看
题意:长度为N的数组,进行m次操作,
分为两种操作:
操作1:U A B 把位置A上的更新为B,
操作2: Q A B 输出[A,B]上的最长连续上升子序列
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308
思路:
操作1,:单点更新
操作2:求连续的上升子序列,区间合并,
线段树节点维护三个值,这个子序列的左边开始的个数,右边开始的个数,这个区间的子序列的个数
和poj 3368多了一点在于单点更新~~~
分为两种操作:
操作1:U A B 把位置A上的更新为B,
操作2: Q A B 输出[A,B]上的最长连续上升子序列
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308
思路:
操作1,:单点更新
操作2:求连续的上升子序列,区间合并,
线段树节点维护三个值,这个子序列的左边开始的个数,右边开始的个数,这个区间的子序列的个数
和poj 3368多了一点在于单点更新~~~
#include <iostream> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define maxn 100010 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int n,m; int val[maxn]; struct segnode{ int lnum,rnum,num; }; segnode tree[maxn<<2]; void PushUp(int rt,int l,int r){ int m = (l + r)/2; tree[rt].lnum = tree[rt<<1].lnum; tree[rt].rnum = tree[rt<<1|1].rnum; tree[rt].num = max(tree[rt<<1].num , tree[rt<<1|1].num); if(val[m] < val[m+1]){ if(tree[rt<<1].lnum == (m - l + 1)) tree[rt].lnum += tree[rt<<1|1].lnum; if(tree[rt<<1|1].rnum == (r - m)) tree[rt].rnum += tree[rt<<1].rnum; tree[rt].num = max(tree[rt].num,(tree[rt<<1].rnum + tree[rt<<1|1].lnum)); } } void build(int l,int r,int rt){ if(l == r){ tree[rt].lnum = 1; tree[rt].rnum = 1; tree[rt].num = 1; return ; } int m = (l + r)/2; build(lson); build(rson); PushUp(rt,l,r); } void update(int pos,int c,int l,int r,int rt){ if(l == r){ val[pos] = c; return ; } int m = (l + r)/2; if(pos <= m) update(pos,c,lson); else update(pos,c,rson); PushUp(rt,l,r); } int query(int L,int R,int l,int r,int rt){ if(L <= l && r <= R){ return tree[rt].num; } int m = (l + r)/2; if(R <= m) return query(L,R,lson); else if(L > m) return query(L,R,rson); else{ int lans = query(L,m,lson); int rans = query(m+1,R,rson); if(val[m] < val[m+1]){ int temp = min(tree[rt<<1].rnum ,(m - L + 1)) + min(tree[rt<<1|1].lnum , R - m); return max(temp,max(lans,rans)); } else{ return max(lans,rans); } } } int main() { int T; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&val[i]); build(1,n,1); while(m--){ char op[10]; int a,b; scanf("%s %d %d",op,&a,&b); if(op[0]=='U'){ update(a+1,b,1,n,1); } else{ printf("%d\n",query(a+1,b+1,1,n,1)); } } } return 0; }
相关文章推荐
- 线段树题集
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 1622 Trees On The Level
- HDU 1063 Exponentiation
- 线段树
- hdu 1202
- HDU 4332(状态压缩dp+矩阵连乘)
- HDU 3065(ac自动机)
- HDU 4714 Tree2cycle
- HDU 4709 Herding
- SPOJ GSS1 Can you answer these queries I
- SPOJ GSS3 Can you answer these queries III
- HDU 4717 The Moving Points
- HDU 4722 Good Numbers
- SPOJ GSS3 Can you answer these queries III
- SPOJ GSS3 Can you answer these queries III