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] 分析:经典的区间覆盖问题,百度可以搜到这个 ...
随机推荐
- opencv自带fast_math.hpp
cvRound cvFloor cvCeil cvIsNaN cvIsInf
- Kafka-Flume-elasticsearch
a1.sources = kafkaSource a1.channels = memoryChannel a1.sinks = elasticsearch a1.sources.kafkaSource ...
- Junit概述
Junit -> java unit.也就是说Junit是xunit家族中的一员. unit <- unit test case,即单元测试用例. Junit = java uni ...
- Python __slots__ 作用
参考:https://blog.csdn.net/u010733398/article/details/52803643 https://blog.csdn.net/sxingming/artic ...
- 使用ultraiso制作启动盘安装windows操作系统
1. 使用ultraiso制作u盘启动盘 在电脑上安装ultraiso: 启动ultraiso,文件->打开->选中iso镜像文件 菜单栏->启动->写入硬盘映像 a. 便捷启 ...
- chrome版本下载
chrome 下载:https://www.chromedownloads.net/chrome64win/ chromedriver下载:http://chromedriver.storage.go ...
- 转 JQuery:常用方法一览
出处 :http://www.cnblogs.com/Fooo/archive/2010/02/01/1661157.html 代码 Attribute:$(”p”).addClass(css中定义的 ...
- How to vi
h:left,j:down,k:up,l:right.wq #write and quitx #cut one letterdd#cut one line/ #searchs/a/b/ #replac ...
- 9.Pod控制器概念和基本操作2
利用一个简单的例子来启动一个deployment的Pod控制器 [root@master song]# cat deploy.yml apiVersion: apps/v1 kind: Deploym ...
- k8s(一) kubeadm简单集群初始化
写给想入门kubernetes的同学们 # 系统版本 [root@master ~]# cat /etc/os-release NAME="CentOS Linux" VERSIO ...