先是nlogn的LIS解法

/*
LIS nlogn解法
*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
//结尾的数字越小,说明相同长度下当前序列越优
int lis[],a[];//lis[i]表示长度为i的最优的结尾数
int n,len=;
int find(int x){//找到lis中第一个大于等于x的数的下标
int l=,r=len;
while(l<r){
int mid=l+r>>;
if(lis[mid]>=x)
r=mid;
else l=mid+;
}
return l;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
lis[]=a[];len++;
for(int i=;i<=n;i++){//按顺序处理每一个数
if(a[i]>lis[len])//可以更新新长度了
lis[++len]=a[i];
else{//对于一个a[i],可以更新以它为结尾的最长lis的结尾
int pos=find(a[i]);//找到lis中第一个大于等于a[i]的数,pos也是以那个数结尾的长度
lis[pos]=a[i]; //把那个数替换了
}
}
printf("%d\n",len);
return ;
}

线段树解LIS

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 10005
int len[maxn<<];
int dp[maxn];
int a[maxn];
void build(int l,int r,int rt){
if(l==r){
len[rt]=;
return;
}
int m=l+r>>;
build(lson);
build(rson);
}
void pushup(int rt){
len[rt]=max(len[rt<<],len[rt<<|]);
}
void update(int pos,int val,int l,int r,int rt){
if(l==r){
len[rt]=val;
return;
}
int m=l+r>>;
if(pos<=m) update(pos,val,lson);
else update(pos,val,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){
return len[rt];
}
int m=l+r>>;
if(R<=m) return query(L,R,lson);
else if(L>=m) return query(L,R,rson);
return max(query(L,m,lson),query(m+,R,rson));
}
int main(){
int n;
while(scanf("%d",&n)==){
int temp=-;
memset(dp,,sizeof dp);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
temp=max(temp,a[i]);
}
build(,temp,);
int ans=;
//找到以小于a[i]的值为结尾的lis,值+1保存在dp[i]中,下一步再把这个dp值更新到线段树中
for(int i=;i<=n;i++){
if(i!=) update(a[i-],dp[i-],,temp,);
if(a[i]>=)
dp[i]=query(,a[i]-,,temp,)+;
else dp[i]=;//a[i]是0的情况
ans=max(ans,dp[i]);
}
printf("%d\n",ans);
}
return ;
}

hdu4521 求间隔为d的lis

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 100010
int a[maxn],dp[maxn],n,d;//用dp存储以第i个数为结尾的lis
int tree[maxn<<];//保存以【l,r】结尾的lis
inline void pushup(int rt){
tree[rt]=max(tree[rt<<],tree[rt<<|]);
}      
void build(int l,int r,int rt){
if(l==r){
tree[rt]=;
return;
}   
int m=l+r>>;
build(lson);
build(rson);
pushup(rt);
}      
//把val更新到pos位置,以pos值结尾的lis为val
void update(int pos,int val,int l,int r,int rt){
if(l==r){
tree[rt]=val;
return;
}    
int m=l+r>>;
if(pos<=m)
update(pos,val,lson);
else   
update(pos,val,rson);
pushup(rt);
}      
//查询值在【L,R】之间的最大lis
int query(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){
return tree[rt];
}
int m=l+r>>,ret=-;
if(R<=m) return query(L,R,lson);
else if(L>m) return query(L,R,rson);
else return max(query(L,m,lson),query(m+,R,rson));
// return ret;
}
int main(){
int temp,ans;
while(scanf("%d%d",&n,&d)==){
ans=temp=-;
memset(dp,,sizeof dp);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
temp=max(temp,a[i]);//找到最大的值
}
build(,temp,);//线段树的区间是0-temp,必须从0开始
for(int i=;i<=n;i++){
if(i-d->=)//必须相隔d+1及以上,把这个点更新进去
update(a[i-d-],dp[i-d-],,temp,);
if(a[i]>=)//找到之前更新以数值小于a[i]为结尾的最长lis
dp[i]=query(,a[i]-,,temp,)+;
else dp[i]=;
ans=max(ans,dp[i]);
}
printf("%d\n",ans);
}
}

线段树解LIS的更多相关文章

  1. cf1132G 线段树解分区间LIS(一种全新的线段树解LIS思路)+单调栈

    /* 给定n个数的数列,要求枚举长为k的区间,求出每个区间的最长上升子序列长度 首先考虑给定n个数的数列的LIS求法:从左往右枚举第i点作为最大点的贡献, 那么往左找到第一个比a[i]大的数,设这个数 ...

  2. Codeforces.264E.Roadside Trees(线段树 DP LIS)

    题目链接 \(Description\) \(Solution\) 还是看代码好理解吧. 为了方便,我们将x坐标左右反转,再将所有高度取反,这样依然是维护从左到右的LIS,但是每次是在右边删除元素. ...

  3. 线段树解Insertion Sort Advanced Analysis

    题目出处 题意描述: 这个题目提问的是,在插入排序的序列给定的情况下,求最少需要移动的次数. 序列的长度n <=10^5 序列中的元素a[i] <=10^6 一组数据中case数t < ...

  4. 2018.10.20 NOIP模拟 蛋糕(线段树+贪心/lis)

    传送门 听说是最长反链衍生出的对偶定理就能秒了. 本蒟蒻直接用线段树模拟维护的. 对于第一维排序. 维护第二维的偏序关系可以借助线段树/树状数组维护逆序对的思想建立权值线段树贪心求解. 代码

  5. POJ - 3264 Balanced Lineup 线段树解RMQ

    这个题目是一个典型的RMQ问题,给定一个整数序列,1~N,然后进行Q次询问,每次给定两个整数A,B,(1<=A<=B<=N),求给定的范围内,最大和最小值之差. 解法一:这个是最初的 ...

  6. 1521. War Games 2(线段树解约瑟夫)

    1521 根据区间和 来确定第k个数在哪 #include <iostream> #include<cstdio> #include<cstring> #inclu ...

  7. poj2299--B - Ultra-QuickSort(线段树,离散化)

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 41215   Accepted: 14915 ...

  8. hdu 1394 Minimum Inversion Number(这道题改日我要用线段树再做一次哟~)

    Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of ...

  9. cf842D 01字典树|线段树 模板见hdu4825

    一般异或问题都可以转换成字典树的问题,,我一开始的想法有点小问题,改一下就好了 下面的代码是逆向建树的,数据量大就不行 /*3 01字典树 根据异或性质,a1!=a2 ==> a1^x1^..^ ...

随机推荐

  1. 5G时代的到来,会给生活带来什么改变?

    本文首发于:风云社区. 据百度百科介绍,5G网络是第五代移动通信网络,其峰值理论传输速度可达每秒数十Gb,比4G网络的传输速度快数百倍.举例来说,整部超高画质电影可在1秒之内下载完成.   5G网络已 ...

  2. MapReduce与关系型数据库的不同之处。

    MapReduce能够被视为RDBMS(关系型数据库)的补充. 1.MapReduce适合处理那些需要分析整个数据集的问题(日志分析等),以批处理的方式.RDBMS适合做点查询和更新. 2.MapRe ...

  3. Linux记录-TCP状态以及(TIME_WAIT/CLOSE_WAIT)分析(转载)

    1.TCP握手定理 2.TCP状态 l  CLOSED:初始状态,表示TCP连接是“关闭着的”或“未打开的”. l  LISTEN :表示服务器端的某个SOCKET处于监听状态,可以接受客户端的连接. ...

  4. xml合并工具【原】

    我的xml文章 xml转换: xml/map转换器 xml合并: xml合并 dupliate()方法思路图: 左报文为: <PACKET> <HEAD> <REQUES ...

  5. bzoj千题计划303:bzoj4827: [Hnoi2017]礼物

    https://www.lydsy.com/JudgeOnline/problem.php?id=4827 式子化简一下,发现最后只跟 Σ xi*yi 有关 第二个序列反转,就可以用FFT优化 注意: ...

  6. SpringMVC学习笔记_01

    1.JAVAEE体系结构 JAVAEE体系结构图如下所示: 2.什么是springmvc? 什么是mvc? Model1 Model2 SpringMVC是什么? SpringMVC是一个web层mv ...

  7. VMware虚拟机Mac OS X无法调整扩展硬盘大小的解决方案(转)

    使用VMware虚拟机搭建的MacOSX,在10.10以上可能会出现无法扩充磁盘大小的问题. 因为很多朋友在初次安装MacOSX的时候都默认选择40G的磁盘大小,结果用了没两天之后就发现磁盘不够用了. ...

  8. java Future模式的使用

    一.Future模式的使用. Future模式简述 传统单线程环境下,调用函数是同步的,必须等待程序返回结果后,才可进行其他处理. Futrue模式下,调用方式改为异步. Futrue模式的核心在于: ...

  9. golang string int int64转换

    #string到int int,err:=strconv.Atoi(string) #string到int64 int64, err := strconv.ParseInt(string, 10, 6 ...

  10. python - class类 (二) 静态属性/类方法/静态方法

    静态属性: #静态属性 = 数据属性 (@property) class mianji(): def __init__(self,x,y): self.x = x self.y = y #类的函数方法 ...