luogu5010 HMR的LIS III (dp+线段树)
这个东西和最长上升子序列很像
考虑如果已经知道每个位置为开头的LIS长度和个数 f[i],我可以扫一遍 判断这个个数和K的大小,找到第一个长度=len而且个数<K的,这个位置就是要选的 然后K-=个数,len--,再记下来我这次选的是这个位置(以后还要判断当前位置是否在上一个钦定住的范围内),然后接着做
那这玩意怎么求呢,离散化一下 算出每个数能跳到的下一个数的大小的区间 倒着dp 用线段树记以这个权值为开头的最大长度和个数 优化转移就可以了
#include<bits/stdc++.h>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,ll> pa;
const int maxn=5e5+; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,M,Llim,Rlim,L[maxn],R[maxn],a[maxn],tmp[maxn];
int ans[maxn];
ll K;
pa ma[maxn<<],f[maxn]; inline void merge(pa &a,pa b){
if(a.first<b.first) a=b;
else if(a.first==b.first){
a.second+=b.second;
a.second=min(a.second,(ll)1e13+);
}
} inline void update(int p){
ma[p]=make_pair(,);
merge(ma[p],ma[p<<]);merge(ma[p],ma[p<<|]);
} inline void change(int p,int l,int r,int x,pa y){
if(l==r){
merge(ma[p],y);
}else{
int m=l+r>>;
if(x<=m) change(p<<,l,m,x,y);
else change(p<<|,m+,r,x,y);
update(p);
}
} inline void query(int p,int l,int r,int x,int y,pa &z){
if(x>y||x>M) return;
y=min(y,M);
if(x<=l&&r<=y) merge(z,ma[p]);
else{
int m=l+r>>;
if(x<=m) query(p<<,l,m,x,y,z);
if(y>=m+) query(p<<|,m+,r,x,y,z);
}
} int main(){
//freopen("","r",stdin);
int i,j,k;
N=rd(),K=rd(),Llim=rd(),Rlim=rd();
for(i=;i<=N;i++)
a[i]=tmp[i]=rd();
sort(tmp+,tmp+N+);M=unique(tmp+,tmp+N+)-tmp-;
for(i=;i<=N;i++){
L[i]=upper_bound(tmp+,tmp+M+,a[i]+Llim)-tmp;
R[i]=lower_bound(tmp+,tmp+M+,a[i]+Rlim)-tmp-;
a[i]=lower_bound(tmp+,tmp+M+,a[i])-tmp;
// printf("~%d %d %d %d\n",i,a[i],L[i],R[i]);
}
for(i=N;i;i--){
pa re=make_pair(,);
query(,,M,L[i],R[i],re);
if(re.first>=) f[i]=make_pair(re.first+,re.second);
else f[i]=make_pair(,);
change(,,M,a[i],f[i]);
// printf("%d %d %d %d %d %d %d\n",i,L[i],R[i],f[i].first,f[i].second,re.first,re.second);
}
int len=;
for(i=;i<=N;i++)
len=max(len,f[i].first);
printf("%d\n",len);
int lst=-;
for(i=,j=;i<=N;i++){
if(f[i].first!=len||(lst!=-&&(a[i]>R[lst]||a[i]<L[lst]))) continue;
if(f[i].second<K) K-=f[i].second;
else ans[++j]=i,len--,lst=i;
}
for(i=;i<=j;i++)
printf("%d ",ans[i]);
return ;
}
luogu5010 HMR的LIS III (dp+线段树)的更多相关文章
- Codeforces 486E LIS of Sequence(线段树+LIS)
题目链接:Codeforces 486E LIS of Sequence 题目大意:给定一个数组.如今要确定每一个位置上的数属于哪一种类型. 解题思路:先求出每一个位置选的情况下的最长LIS,由于開始 ...
- ZOJ 3349 Special Subsequence 简单DP + 线段树
同 HDU 2836 只不过改成了求最长子串. DP+线段树单点修改+区间查最值. #include <cstdio> #include <cstring> #include ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- cf834D(dp+线段树区间最值,区间更新)
题目链接: http://codeforces.com/contest/834/problem/D 题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, ...
- Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树)
Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树) 题目链接 题意 给定一个nm的矩阵,每行取2k的矩阵,求总 ...
- SP1716 GSS3 - Can you answer these queries III - 动态dp,线段树
GSS3 Description 动态维护最大子段和,支持单点修改. Solution 设 \(f[i]\) 表示以 \(i\) 为结尾的最大子段和, \(g[i]\) 表示 \(1 \sim i\) ...
- UVA-1322 Minimizing Maximizer (DP+线段树优化)
题目大意:给一个长度为n的区间,m条线段序列,找出这个序列的一个最短子序列,使得区间完全被覆盖. 题目分析:这道题不难想,定义状态dp(i)表示用前 i 条线段覆盖区间1~第 i 线段的右端点需要的最 ...
- POJ1769 Minimizing maximizer(DP + 线段树)
题目大概就是要,给一个由若干区间[Si,Ti]组成的序列,求最小长度的子序列,使这个子序列覆盖1到n这n个点. dp[i]表示从第0个到第i个区间且使用第i个区间,覆盖1到Ti所需的最少长度 对于Si ...
- [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)
题目:http://poj.org/problem?id=3171 题意:给你n个区间[a,b],每个区间都有一个费用c,要你用最小的费用覆盖区间[M,E] 分析:经典的区间覆盖问题,百度可以搜到这个 ...
随机推荐
- JavaScript修改DOM节点时,样式优先级的问题
通过element.style.xxx设置或者读取的xxx样式属性,都是属于行间样式(<p style="color=red"></p>),并不是 使用li ...
- LINUX操作系统(centos6.9)安装与配置
LINUX操作系统(centos6.9)安装与配置_百度经验 https://jingyan.baidu.com/article/acf728fd6bdba1f8e510a3f7.html cento ...
- react双组件传值和传参
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [转帖]NotePad++编辑Linux中的文件
NotePad++编辑Linux中的文件 https://blog.csdn.net/chengqiuming/article/details/78882692 原作者 未经允许不允许转帖 加密自己参 ...
- java语句中的重定向函数
重定向后面就不能转发了,所以return null
- QueryRunner 错误
QueryRunner qr=new QueryRunner(JDBCUtils.getDataSource()); 写成了 QueryRunner qr = new QueryRunner(); 导 ...
- 关于idea easyui 引入css js
1.引用官方网站 <link rel="stylesheet" type="text/css" href="http://www.w3cscho ...
- 如何在mac下安装php
步骤如下: 1.下载php源码并解压 2.进入php源码并configure 3.安装openssl 4.sudo make及make test 5.sudo make install 具体命令如下: ...
- Yii2上传图片插件使用
例子: 1.在表单中: <?php $form = \yii\widgets\ActiveForm::begin([ 'options'=>[ 'class' => 'form-ho ...
- Ajax之Jquery封装使用举例2(Json和JsonArray处理)
本例主要使用ajax进行异步数据请求,并针对返回数据为json和jsonarray类型的数据处理. 本例中只有前端的代码,后端代码不是本文重点,故省略. 后端接口返回数据为: Json: {" ...