HDU 3308 LCIS(线段树)
2014-11-02 21:47
309 查看
题目:
Input:
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).
Output:
For each Q, output the answer.
题意:
此题要求实现对已存数据的更新和查询出给出的范围内最大递增区间的长度,故可以线段树成段更新来解决。
Input:
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).
Output:
For each Q, output the answer.
题意:
此题要求实现对已存数据的更新和查询出给出的范围内最大递增区间的长度,故可以线段树成段更新来解决。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define MAX 100000 using namespace std; int Max[MAX<<2],lmax[MAX<<2],rmax[MAX<<2],val[MAX],flag[MAX<<2]; void pushup(int l,int r,int root) { int mid=(l+r)>>1; lmax[root]=lmax[root<<1]; rmax[root]=rmax[root<<1|1]; Max[root]=max(Max[root<<1],Max[root<<1|1]); if(val[mid]<val[mid+1]) { if(flag[root<<1])//左孩子满 lmax[root]+=lmax[root<<1|1]; if(flag[root<<1|1])//右孩子满 rmax[root]+=rmax[root<<1]; Max[root]=max(Max[root],rmax[root<<1]+lmax[root<<1|1]);//取父节点长度与左右孩子长度和的较大值 } if(Max[root]==r-l+1)//此分支已为满 { flag[root]=1; } else { flag[root]=0; } } void buildtree(int l,int r,int root) { Max[root]=1; lmax[root]=1; rmax[root]=1; flag[root]=1; if(l==r) { scanf("%d",&val[l]); return; } int mid=(l+r)>>1; buildtree(l,mid,root<<1); buildtree(mid+1,r,root<<1|1); pushup(l,r,root); } void update(int l,int r,int root,int p,int re) { if(l==r) { val[p]=re; return; } int mid=(l+r)>>1; if(p<=mid) { update(l,mid,root<<1,p,re); } else{ update(mid+1,r,root<<1|1,p,re); } pushup(l,r,root); } int query(int l,int r,int root,int L,int R) { if(l>=L&&r<=R)//成段更新 { return Max[root]; } int mid=(l+r)>>1; if(mid>=R) { return query(l,mid,root<<1,L,R); } if(mid<L) { return query(mid+1,r,root<<1|1,L,R); } int ans=max(query(l,mid,root<<1,L,mid),query(mid+1,r,root<<1|1,mid+1,R));//所查区间左右各有,取两者最大值 if(val[mid]<val[mid+1])//所查的中间点两边成递增的情况 { ans=max(ans,min(mid-L+1,rmax[root<<1])+min(R-mid,lmax[root<<1|1]));//取区间两边长度最小值之和与之前没去两边的最大递增长度比较 } return ans; } int main() { int n,m,T,num,a,b; scanf("%d",&T); char ch[10]; while(T--) { scanf("%d%d",&n,&m); buildtree(1,n,1); for(int i=1;i<=m;i++) { scanf("%s",&ch); scanf("%d%d",&a,&b); if(ch[0]=='U') { update(1,n,1,a+1,b); } else{ printf("%d\n",query(1,n,1,a+1,b+1)); } } } 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 LCIS(线段树+区间合并+最长递增连续子串)
- HDU - 3308 - LCIS (线段树 - 区间合并)
- HDU 3308 LCIS 线段树 区间合并 入门题
- 【线段树】HDU 3308 LCIS
- HDU 3308 LCIS(线段树,连续递增子)
- HDU 3308 LCIS 线段树 PushUp应用