hdu 3308 LCIS 线段树
昨天热身赛的简单版:LCIS。昨天那题用树链剖分,不知道哪里写错了,所以水了水这题看看合并、更新方式是否正确,发现没错啊。看来应该是在树链剖分求lca时写错了。。。
题目:给出n个数,有两种操作:
1.单点修改
2.区间询问:最长连续上升子序列
分析:只需要维护五个域就行:lix,rdx,mix,lval,rval。记录当前区间 最左的值lval , 最右的值rval,必须从左起连续上升序列的长度lix,必须右起下降的长度rdx。合并时注意下即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; char IN;
bool NEG;
inline void Int(int &x){
NEG = 0;
while(!isdigit(IN=getchar()))
if(IN=='-')NEG = 1;
x = IN-'0';
while(isdigit(IN=getchar()))
x = x*10+IN-'0';
if(NEG)x = -x;
} inline void Char(char &x){
while(!isupper(x=getchar()));
} /******** program ********************/ const int MAXN = 200105; int son[MAXN],sz[MAXN],top[MAXN],fa[MAXN],tid[MAXN],dep[MAXN],tim;
bool use[MAXN];
int a[MAXN]; struct segTree{
int l,r;
int lval,rval;
int lix,mix;
int rdx;
segTree(){
l = r = lval = rval = 0;
lix = mix = 0;
rdx = 0;
}
inline int mid(){
return (l+r)>>1;
}
inline int dis(){
return r-l+1;
}
}tree[MAXN<<1]; inline void update(segTree &now,segTree l,segTree r){
// lix
if(l.lix==l.dis()&&l.rval<r.lval)
now.lix = l.lix+r.lix;
else now.lix = l.lix; // mix
if(l.rval<r.lval)
now.mix = max(max(l.mix,r.mix),l.rdx+r.lix);
else now.mix = max(l.mix,r.mix); // rdx
if(r.dis()==r.rdx&&r.lval>l.rval)
now.rdx = r.rdx+l.rdx;
else now.rdx = r.rdx; now.lval = l.lval;
now.rval = r.rval;
} void build(int l,int r,int rt){
tree[rt].l = l;
tree[rt].r = r;
if(l==r){
tree[rt].lval = tree[rt].rval = a[l];
tree[rt].lix = tree[rt].mix = 1;
tree[rt].rdx = 1;
return;
}
int mid = tree[rt].mid();
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
update(tree[rt],tree[rt<<1],tree[rt<<1|1]);
} void modify(int pos,int val,int rt){
if(tree[rt].l==tree[rt].r){
tree[rt].lval = tree[rt].rval = val;
return;
}
int mid = tree[rt].mid();
if(pos<=mid)modify(pos,val,rt<<1);
else modify(pos,val,rt<<1|1);
update(tree[rt],tree[rt<<1],tree[rt<<1|1]);
} segTree ask(int l,int r,int rt){
if(l<=tree[rt].l&&tree[rt].r<=r)
return tree[rt];
int mid = tree[rt].mid();
segTree ans;
if(r<=mid)ans = ask(l,r,rt<<1);
else if(l>mid)ans = ask(l,r,rt<<1|1);
else{
segTree a = ask(l,r,rt<<1);
segTree b = ask(l,r,rt<<1|1);
update(ans,a,b);
}
update(tree[rt],tree[rt<<1],tree[rt<<1|1]);
return ans;
} int main(){ #ifndef ONLINE_JUDGE
freopen("sum.in","r",stdin);
//freopen("sum.out","w",stdout);
#endif char op;
int n,m,ncase,x,y;
Int(ncase);
while(ncase--){
Int(n);Int(m);
for(int i=1;i<=n;i++)
Int(a[i]);
build(1,n,1);
while(m--){
Char(op);
Int(x);Int(y);
if(op=='Q')printf("%d\n",ask(++x,++y,1).mix);
else modify(++x,y,1);
}
} return 0;
}
hdu 3308 LCIS 线段树的更多相关文章
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
- HDU 3308 LCIS(线段树单点更新区间合并)
LCIS Given n integers. You have two operations: U A B: replace the Ath number by B. (index counting ...
- HDU 3308 LCIS (线段树·单点更新·区间合并)
题意 给你一个数组 有更新值和查询两种操作 对于每次查询 输出相应区间的最长连续递增子序列的长度 基础的线段树区间合并 线段树维护三个值 相应区间的LCIS长度(lcis) 相应区间以左 ...
- HDU 3308 LCIS 线段树区间更新
最近开始线段树一段时间了,也发现了不少大牛的博客比如HH大牛 ,小媛姐.这个题目是我在看HH大牛的线段树专题是给出的习题,(可以去他博客找找,真心推荐)原本例题是POJ3667 Hotel 这个题目 ...
- HDU 3308 LCIS(线段树)
题目链接 模板题吧,忘了好多,终于A了... #include <cstring> #include <cstdio> #include <string> #inc ...
- LCIS HDU - 3308 (线段树区间合并)
LCIS HDU - 3308 Given n integers. You have two operations: U A B: replace the Ath number by B. (inde ...
- HDU 3308 (线段树区间合并)
http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作 : 1 修改 单点 a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...
- hud 3308 LCIS 线段树 区间合并
题意: Q a b 查询[a, b]区间的最长连续递增子序列的长度 U a b 将下表为a的元素更新为b 区间合并一般都有3个数组:区间最值,左区间最值和右区间最值 具体详见代码 #include & ...
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
随机推荐
- OSG+MFC对话框程序
OSG的sample里面有OSG+MFC+MDI的例子. 网上有说OSG+MFCSDI的例子,如http://blog.csdn.net/xuguangsoft/article/details/816 ...
- cocos2d-x 使用Lua
转自:http://www.benmutou.com/blog/archives/49 1. Lua的堆栈和全局表 我们来简单解释一下Lua的堆栈和全局表,堆栈大家应该会比较熟悉,它主要是用来让C++ ...
- On-board diagnostics connector SAE J1962
http://en.wikipedia.org/wiki/On-board_diagnostics#Standard_interfaces OBD-II diagnostic connector Th ...
- 关于c#中的Timer控件的简单用法
Timer控件主要会用到2个属性一个是Enabled和IntervalEnabled主要是控制当前Timer控件是否可用timer1.Enabled=false;不可用timer1.Enabled=t ...
- BZOJ 1084: [SCOI2005]最大子矩阵 DP
1084: [SCOI2005]最大子矩阵 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1084 Description 这里有一个n* ...
- 都是iconv惹的祸
今天在做采集的时候发现只取到了网页的部分内容,当时我就郁闷了,之前都用的采集都可以采集到网页的所有内容,但这次死活就取到部分内容.寻找原因才知道原来是iconv惹的祸. 发现问题时,网上搜了搜,才发现 ...
- Eclipse中SVN的安装步骤(两种)和用法
一.给安装EclipseSVN,最常见的有两种方式:手动方式和使用安装向导方式.详细过程例如以下: 方式一:手动安装 1.从官网下载site-1.6.9.zip文件,网址是:subclipse.tig ...
- Deep Learning(深度学习)学习笔记整理系列之(五)
Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...
- Android Widget 小部件(三) 在Activity中加入Widget
package com.stone.ui; import static android.util.Log.d; import android.app.Activity; import android. ...
- IO端口和IO内存的区别 转
目录(?)[-] Linux系统对IO端口和IO内存的管理 一.I/O端口 二.IO内存 三.IO端口和IO内存的区分及联系 四.外设IO端口物理地址的编址方式 统一编址 独立编址 优缺点 五.L ...