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] 分析:经典的区间覆盖问题,百度可以搜到这个 ...
随机推荐
- Pseudo Registers
Pseudoregister Description @ERR Last error value; the same value returned by the GetLastError() API ...
- ipython安装( jupyter)
生产环境:win10 64位 pip的版本不是最新的,输入命令 python -m pip install --upgrade pip 更新我们的pip,pip不是最新的也会导致安装不了ipython ...
- # 【Python3练习题 003】一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
# -------------------------------------------------## 所谓的“完全平方数”,就是开完根号仍然是整数.## 数学渣是这么思考的:假设这个数 i 在1 ...
- 了解真实的rem手机屏幕适配
rem 作为一个低调的长度单位,由于手机端网页的兴起,在屏幕适配中得到重用.使用 rem 前端开发者可以很方便的在各种屏幕尺寸下,通过等比缩放的方式达到设计图要求的效果. rem 的官方定义『The ...
- innerText兼容问题处理
IE.Safari.Opera和Chrome支持innerText属性.低版本的火狐浏览器不支持,但支持作用类似的textContent属性.textContent是DOM3级规定的一个属性,而且也得 ...
- Java中的super()使用注意
1)super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句)2)this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)3)super: 它引用当前对象的 ...
- rabbitmq 配置
1, 安装 apt-get install rabbitmq-server -y 2, 打开管理页面 sudo rabbitmq-plugins enable rabbitmq_management ...
- windows 安装tensorflow
原文知乎:https://zhuanlan.zhihu.com/p/25778703 前言 看到Rstudio中开始支持Tensorflow,本人是欣喜若狂的,同时TensorFlow官网从16年9月 ...
- python functools.wraps functools.partial实例解析
一:python functools.wraps 实例 1. 未使用wraps的实例 #!/usr/bin/env python # coding:utf-8 def logged(func): de ...
- MySQL创建远程用户并授权
今天需要在本地测试系统功能,因为本地没有数据库,就需要在程序里面连接远程数据库: 先用ssh登录远程服务器,用root连上数据库看看情况: mysql> select Host,User,Pas ...