hdu 3308 LCIS (线段树单点更新)
2013-10-21 22:11
337 查看
题目大意:
U a b 把第a个数变成b
Q a b 询问[a,b]中最长连续递增区间
思路:
如POJ 3667 hotel
只要在pushup的时候判断一下左端点是不是比右端点小就可以了
U a b 把第a个数变成b
Q a b 询问[a,b]中最长连续递增区间
思路:
如POJ 3667 hotel
只要在pushup的时候判断一下左端点是不是比右端点小就可以了
#include <iostream> #include <cstdio> #include <algorithm> #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e #define maxn 100005 using namespace std; int lem[maxn<<2]; int rim[maxn<<2]; int tre[maxn<<2];//最大连续递增区间 int lez[maxn<<2];//区间左端点的值 int riz[maxn<<2];//----右-------- void pushup(int num,int s,int e) { int mid=(s+e)>>1; lem[num]=lem[num<<1]; rim[num]=rim[num<<1|1]; lez[num]=lez[num<<1]; riz[num]=riz[num<<1|1]; if(lem[num]==mid-s+1) { if(riz[num<<1]<lez[num<<1|1])//注意一下这个判断就好 lem[num]+=lem[num<<1|1]; } if(rim[num]==e-mid) { if(riz[num<<1]<lez[num<<1|1]) rim[num]+=rim[num<<1]; } int tmp=0; if(riz[num<<1]<lez[num<<1|1]) tmp = rim[num<<1]+lem[num<<1|1]; tre[num] = max(tmp,max(tre[num<<1],tre[num<<1|1])); } void debug(int num,int s,int e)//=。= debug debug 多好的debug啊 { printf("s = %d,e = %d,lem = %d,rim = %d,tre = %d\n",s,e,lem[num],rim[num],tre[num]); if(s==e)return; int mid=(s+e)>>1; debug(lson); debug(rson); } void build(int num,int s,int e) { if(s==e) { scanf("%d",&lez[num]); riz[num]=lez[num]; lem[num]=rim[num]=tre[num]=1; return; } int mid=(s+e)>>1; build(lson); build(rson); pushup(num,s,e); } int query(int num,int s,int e,int l,int r) { if(l<=s && r>=e) { return tre[num]; } int mid=(s+e)>>1; if(r<=mid)return query(lson,l,r); else if(l>mid)return query(rson,l,r); else { int L=min(mid-l+1,rim[num<<1]);//这里也是比较不好想的 int R=min(r-mid,lem[num<<1|1]); int tmp=0; if(riz[num<<1]<lez[num<<1|1])tmp=L+R; return max(tmp,max(query(lson,l,r),query(rson,l,r))); } } void update(int num,int s,int e,int pos,int val) { if(s==e) { lez[num]=riz[num]=val; rim[num]=lem[num]=1; tre[num]=1; return; } int mid=(s+e)>>1; if(pos<=mid)update(lson,pos,val); else if(pos>mid)update(rson,pos,val); pushup(num,s,e); } int main() { int T; int n,m; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); build(1,1,n); //debug(1,1,n); while(m--) { char op[5]; int a,b; scanf("%s%d%d",op,&a,&b); if(op[0]=='U')a++,update(1,1,n,a,b); else a++,b++,printf("%d\n",query(1,1,n,a,b)); } } return 0; }
相关文章推荐
- 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 (线段树·单点更新·区间合并)
- HDU 3308 线段树 最长连续上升子序列 单点更新 区间查询
- HDU 3308 LCIS 线段树的单点更新,区间合并
- HDU 3308 线段树单点更新+区间查找最长连续子序列
- hdu 3308 线段树单点更新 区间合并
- hdu 3308 LCIS(单点更新,区间合并)
- HDU 3308 线段树 最长连续上升子序列 单点更新 区间查询