【线段树】HDU 3308 LCIS
来源:互联网 发布:七夕表白源码 编辑:程序博客网 时间:2024/05/01 13:49
= =
两种操作:
U A B:将A位置更新为B
Q A B:求A-B区间内的最长连续上升子序列的长度
需要四个数组
用num 表示序列
用sum 表示该储存该子树的最长连续上升子序列的长度
用lsum 表示该储存该子树的从子树的第一个num开始的最长连续上升子序列的长度
rsum则表示从结束于该子树最后一个num的最长连续上升子序列的长度
更新操作只需要单点更新即可
在pushup时
rt节点的lsum继承了左子节点的lsum
rt节点的rsum继承了右子节点的rsum
rt的sum则需要取左右子节点的sum最大值以及比较两子节点下的num可能连续形成新的上升序列;
同样查询操作时同样是取左右子节点的最大值和可能形成新的子序列;
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <string>#include <iostream>#include <algorithm>using namespace std;#include <queue>#include <stack>#include <vector>#include <deque>#include <set>#include <map>#define IN freopen ("in.txt" , "r" , stdin);#define OUT freopen ("out.txt" , "w" , stdout);typedef long long LL;const int MAXN = 100110;//点数的最大值const int MAXM = 20006;//边数的最大值const int INF = 11521204;const int mod=1000000007;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int num[MAXN];int sum[MAXN<<2],lsum[MAXN<<2],rsum[MAXN<<2];int col[MAXN<<2];void pushup(int rt,int m,int l){ int lx=m-(m>>1); int rx=(m>>1); lsum[rt]=lsum[rt<<1]; rsum[rt]=rsum[rt<<1|1]; if(lsum[rt]==lx&&num[lx+l-1]<num[lx+l]) lsum[rt]+=lsum[rt<<1|1]; if(rsum[rt]==rx&&num[lx+l-1]<num[lx+l]) rsum[rt]+=rsum[rt<<1]; sum[rt]=max(max(sum[rt<<1],sum[rt<<1|1]),num[lx+l-1]<num[lx+l]?rsum[rt<<1]+lsum[rt<<1|1]:0);}void build(int l,int r,int rt){ col[rt]=0; if(l==r) { scanf("%d",&num[l]); sum[rt]=lsum[rt]=rsum[rt]=1; return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt,r-l+1,l);}void update(int x,int cc,int l,int r,int rt){ if(l==r) { num[l]=cc; return ; } int m=(l+r)>>1; if(x<=m) update(x,cc,lson); else update(x,cc,rson); pushup(rt,r-l+1,l);}int query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R) { return sum[rt]; } int m=(l+r)>>1,res=0; if(L<=m) res=max(res, query(L,R,lson)); if(m<R) res=max(res,query(L,R,rson)); if (num[m] < num[m+1]) res = max(res, min(m-L+1, rsum[rt<<1])+min(R-m, lsum[rt<<1|1])); return res;}int main(){ int n,m,t; IN; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); build(1,n,1); while(m--) { char c[2]; int a,b; scanf("%s%d%d",c,&a,&b); if(c[0]=='U') update(a+1,b,1,n,1); else printf("%d\n",query(a+1,b+1,1,n,1)); } } return 0;}
0 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(线段树)
- 【线段树求LCIS】HDU 3308
- hdu 3308 LCIS 线段树 区间合并
- hdu 3308 线段树区间 LCIS
- hdu 3308 LCIS (线段树)
- hdu 3308LCIS 线段树 区间合并
- [HDU 3308]LCIS[线段树][区间合并]
- HDU 3308 LCIS 线段树区间更新
- Java中static、final用法小结
- 一个令人蛋疼的NDK链接错误
- 华为离职副总裁徐家骏:年薪千万的工作感悟
- 个人对openAL的看法
- cocos2dx 3.1.1官方demo阅读-ActionsProgressTest【进度条】
- 【线段树】HDU 3308 LCIS
- Pasha and Hamsters
- 安装 Linux 应知的十件事
- 立体影片格式全面全解析
- lua基础
- 10年软件测试工作总结
- 表达式中缀转后缀
- Winform 快捷键设置
- poj 2485 Highways(最小生成树 Prim)