HDOJ 3308 LCIS
来源:互联网 发布:mac os x系统 编辑:程序博客网 时间:2024/05/17 04:01
跟POJ3667hotel差不多,三个数组分别记录左右和总区间,维护时注意左右,重点是query函数,没啥想法,这里参考了下别人的代码。单独拉出query函数吧
主要是如何处理横跨左右区间的查询
int query(int L,int R,int l,int r,int rt)
{
int m=(l+r)>>1;
if(L<=l&&r<=R)return msum[rt];
int ans=0;
if(R<=m)ans=max(ans,query(L,R,lson));
else if(L>m)ans=max(ans,query(L,R,rson));
else
{
ans=max(ans,query(L,R,lson));
ans=max(ans,query(L,R,rson));
int left;
int right;
if(m-L+1>=rsum[rt<<1])left=rsum[rt<<1];//左边
else left=m-L+1;
if(R-m>=lsum[rt<<1|1])right=lsum[rt<<1|1];//右边
else right=R-m;
ans=max(ans,left);
ans=max(ans,right);
if(a[m]<a[m+1])
ans=max(ans,left+right);
}
return ans;
}
完整代码:
#include <cstdio>#include <algorithm>#include<stdio.h>#include<stdlib.h>#include<string.h>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define N 100005int a[N];int lsum[N<<2];int rsum[N<<2];int msum[N<<2];void pushup(int l,int r,int rt){ int m=(l+r)>>1; lsum[rt]=lsum[rt<<1]; rsum[rt]=rsum[rt<<1|1]; if(lsum[rt]==m-l+1&&a[m]<a[m+1])lsum[rt]+=lsum[rt<<1|1]; if(rsum[rt]==r-m&&a[m]<a[m+1])rsum[rt]+=rsum[rt<<1]; msum[rt]=max(msum[rt<<1],msum[rt<<1|1]); if(a[m]<a[m+1])msum[rt]=max(msum[rt],rsum[rt<<1]+lsum[rt<<1|1]);}void build(int l,int r,int rt){ if(l==r) { lsum[rt]=rsum[rt]=msum[rt]=1; return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(l,r,rt);}void update(int k,int l,int r,int rt){ if(l==r)return ; int m=(l+r)>>1; if(k<=m)update(k,lson); if(k>m)update(k,rson); pushup(l,r,rt);}int query(int L,int R,int l,int r,int rt){ int m=(l+r)>>1; if(L<=l&&r<=R)return msum[rt]; int ans=0; if(R<=m)ans=max(ans,query(L,R,lson)); else if(L>m)ans=max(ans,query(L,R,rson)); else { ans=max(ans,query(L,R,lson)); ans=max(ans,query(L,R,rson)); int left; int right; if(m-L+1>=rsum[rt<<1])left=rsum[rt<<1]; else left=m-L+1; if(R-m>=lsum[rt<<1|1])right=lsum[rt<<1|1]; else right=R-m; ans=max(ans,left); ans=max(ans,right); if(a[m]<a[m+1]) ans=max(ans,left+right); } return ans;}int main(){ int t,n,m,i,x,y; char b[3]; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%d",&a[i]); build(1,n,1); while(m--) { scanf("%s",b); scanf("%d%d",&x,&y); if(b[0]=='U') { a[x+1]=y; update(x+1,1,n,1); } else { printf("%d\n",query(x+1,y+1,1,n,1)); } } }}
- HDOJ 3308 LCIS
- HDOJ 3308 LCIS
- 【线段树】 HDOJ 3308 LCIS
- hdoj-5904 LCIS
- HDOJ 5904 LCIS
- HDOJ 3308 LCIS (线段树区间合并)
- HDOJ 3308 LCIS (线段树之区间合并)
- HDOJ 5904 LCIS (dp)
- HDOJ 题目3308 LCIS(线段树,区间查询,区间合并)
- hdoj 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
- Unity3D起步学习要点
- poj1001 Exponentiation 解题报告
- 令牌桶算法CAR
- cpu 主频及相关介绍
- VMware-workstation-full-9.0.2-1031769 官方正式版 下载和激活
- HDOJ 3308 LCIS
- iOS开发知识与能力体系 思维导图
- GarsiaWachs算法
- Cognos 10的优点
- 算法导论二:快速排序
- Alias Method解决随机类型概率问题
- 青软实训.NET学习笔记(5)---泛型
- 【iOS】推送通知
- 关于二叉树重建的问题