HDU 3308 线段树 最长连续上升子序列 单点更新 区间查询
2013-10-10 22:05
447 查看
题意:
T个测试数据
n个数 q个查询
n个数 ( 下标从0开始)
Q u v 查询 [u, v ] 区间最长连续上升子序列
U u v 把u位置改成v
T个测试数据
n个数 q个查询
n个数 ( 下标从0开始)
Q u v 查询 [u, v ] 区间最长连续上升子序列
U u v 把u位置改成v
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define N 101010 #define L(x) (x<<1) #define R(x) (x<<1|1) inline int Max(int a,int b){return a>b?a:b;} inline int Min(int a,int b){return a<b?a:b;} struct node { int l,r; int mid(){ return (l+r)>>1; } int len(){ return r-l+1; } int Llen, Rlen, maxlen; }tree[4*N]; int a ; void updata_up(int id){ tree[id].Llen = tree[L(id)].Llen; tree[id].Rlen = tree[R(id)].Rlen; tree[id].maxlen = Max( tree[L(id)].maxlen, tree[R(id)].maxlen); if( a[ tree[L(id)].r ] < a[ tree[R(id)].l ] ) { if( tree[L(id)].Llen == tree[L(id)].len()) { tree[id].Llen += tree[R(id)].Llen; tree[id].maxlen = Max( tree[id].maxlen, tree[id].Llen); } if( tree[R(id)].Rlen == tree[R(id)].len() ) { tree[id].Rlen += tree[L(id)].Rlen; tree[id].maxlen = Max( tree[id].maxlen, tree[id].Rlen); } tree[id].maxlen = Max( tree[id].maxlen, tree[L(id)].Rlen + tree[R(id)].Llen ); } } void build(int l, int r, int id){ tree[id].l = l, tree[id].r = r; if(l==r){ tree[id].Llen = tree[id].Rlen = tree[id].maxlen =1; return ; } int mid = (l+r)>>1; build(l, mid, L(id)); build(mid+1, r, R(id)); updata_up(id); } void updata(int pos,int id){ if(tree[id].l == tree[id].r)return ; int mid = tree[id].mid(); if( pos <= mid ) updata(pos, L(id)); else updata(pos, R(id)); updata_up(id); } int query(int l, int r, int id){ if( l == tree[id].l && tree[id].r == r) return tree[id].maxlen; int mid = tree[id].mid(); if(r <= mid)return query(l, r, L(id)); else if(mid < l) return query(l, r, R(id)); int L = query(l, mid, L(id)), R = query(mid+1, r, R(id)); if( a[mid] < a[mid+1] ){ int LL = Min( mid - l + 1, tree[L(id)].Rlen); int RR = Min( r - mid, tree[R(id)].Llen); return Max( Max(L,R), LL+RR); } else return Max(L, R); } int main(){ int T,n,q,i; scanf("%d",&T); while(T--){ scanf("%d %d", &n, &q); for(i=1;i<=n;i++)scanf("%d",&a[i]); build(1, n, 1); while(q--) { char c = '-'; while(c!='Q' && c!='U') c = getchar(); int u,v; scanf("%d %d", &u, &v); if(c == 'Q') printf("%d\n", query(u+1, v+1, 1)); else if(c == 'U') { a[u+1] = v; updata(u+1, 1); } } } return 0; } /* 99 10 10 7 7 3 3 5 9 9 8 1 8 Q 6 6 U 3 4 Q 0 1 Q 0 5 Q 4 7 Q 3 5 Q 0 2 Q 4 6 U 6 10 Q 0 9 10 99 1 2 3 4 5 6 7 8 9 10 Q 4 7 U 0 8 Q 0 9 U 8 8 Q 0 9 */
相关文章推荐
- HDU 3308 线段树 最长连续上升子序列 单点更新 区间查询
- HDU 3308【线段树-query:区间最长单调上升序列,update:结点更新,区间合并】
- HDU 3308 LCIS 最长连续递增序列+数据结构+线段树+单点更新
- HDU 3308 线段树单点更新+区间查找最长连续子序列
- hdu 3308 线段树-区间连续最长上升子序列
- HDU 3308 LCIS(最长连续上升子序列)(线段树区间合并)
- hdu 3308 线段树 区间合并+单点更新+区间查询
- HDU 3308 最长上升连续子序列 (线段树)
- HDU - 3308 LCIS (线段树 单点更新 区间查询)
- HDU 1556 给连续个球涂色-线段树-(区间更新,单点查询)
- hdoj 3308 LCIS 【线段树单点更新 + 区间合并】【求解最长递增序列 的长度】
- kuangbin专题七 : B题 :HDU 1754 I Hate It(线段树单点更新区间查询最值)
- HDU 1166 敌兵布阵 (线段树单点更新 区间查询)
- HDU-1166 敌兵布阵【简单线段树-单点更新+区间查询】
- HDU 4819 Mosaic(二维线段树单点更新+区间查询+自己的写法模板)
- HDU1754线段树单点更新区间查询(数组版)
- HDU 3308 LCIS(线段树区间合并 单点更新)
- HDU 1540——Tunnel Warfare(线段树,区间合并+单点更新+单点查询)
- HDU 3308 LCIS(线段树单点更新区间合并)
- HDU 1166 敌兵布阵 (线段树单点更新 区间查询)