题解-CF1437E Make It Increasing
题面
给 \(n\) 个数 \(a_i\),固定 \(k\) 个下标 \(b_i\),求只修改不在 \(b_i\) 中的下标的值使 \(a_i\) 严格单调递增的最少修改次数。
数据范围:\(1\le n\le 5\cdot 10^5\),\(0\le k\le n\)。
题解
分成 \(k+1\) 段做没有问题,蒟蒻的做法是线段树维护 dp。
旁边老爷的做法是区间长度减去最长上升子序列长度,蒟蒻没想到,还想了单调队列优化好久。
题目转化为对于一个区间,第一个元素最后一个元素固定的最少修改次数。
把 \(a_i\) 减去 \(i\),就变成非严格单调递增了。
设 \(f_i\) 表示不修改 \(i\) 的前缀最少修改次数。
\]
所以可以建一个 \(a_i\) 值域线段树,值为 \(f_i-i\)。
\(f_i\) 的值就是当前线段树 \([0,a_i]\) 之间的最大值 \(+i-1\)。
每次求出 \(f_i\) 后在 \(a_i\) 上更新 \(f_i-i\) 即可。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define mp(a,b) make_pair((a),(b))
#define x first
#define y second
#define bg begin()
#define ed end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
#define R(i,a,b) for(int i=(a),i##E=(b);i<i##E;i++)
#define L(i,a,b) for(int i=(b)-1,i##E=(a)-1;i>i##E;i--)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;
//Data
const int N=5e5+2;
int n,a[N],dn,d[N],k,b[N],ans;
//SegmentTree
const int tN=N<<2;
#define mid ((l+r)>>1)
int mn[tN];
void build(int k=0,int l=0,int r=dn){
mn[k]=iinf; if(r-l==1) return;
build(k*2+1,l,mid),build(k*2+2,mid,r);
}
void pushup(int k){mn[k]=min(mn[k*2+1],mn[k*2+2]);}
void fixmn(int x,int v,int k=0,int l=0,int r=dn){
if(r<=x||x+1<=l) return;
if(r-l==1) return mn[k]=min(mn[k],v),void();
fixmn(x,v,k*2+1,l,mid),fixmn(x,v,k*2+2,mid,r),pushup(k);
}
int rangemn(int x,int y,int k=0,int l=0,int r=dn){
if(r<=x||y<=l) return iinf; if(x<=l&&r<=y) return mn[k];
return min(rangemn(x,y,k*2+1,l,mid),rangemn(x,y,k*2+2,mid,r));
}
//DP
int tmp[N];
int dp(int* arr,int len){
R(i,dn=0,len) d[dn++]=arr[i];
sort(d,d+dn),dn=unique(d,d+dn)-d;
R(i,0,len) tmp[i]=lower_bound(d,d+dn,arr[i])-d;
build(),fixmn(tmp[0],0); int res=-1;
R(i,1,len){
res=rangemn(0,tmp[i]+1)+i-1;
fixmn(tmp[i],res-i);
}
// R(i,0,len) cout<<arr[i]<<' ';cout<<'\n';
// R(i,0,len) cout<<f[i]<<' ';cout<<'\n';
// cout<<f[len-1]<<'\n';
return res;
}
//Main
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>k,a[0]=-iinf,a[n+1]=+iinf;
R(i,1,n+1) cin>>a[i],a[i]-=i;
R(i,0,k) cin>>b[i];
R(i,1,k)if(a[b[i]]<a[b[i-1]]) cout<<-1<<'\n',exit(0);
if(k==0) ans=dp(a,n+2);
else {
ans+=dp(a,b[0]+1);
R(i,1,k) ans+=dp(a+b[i-1],b[i]-b[i-1]+1);
ans+=dp(a+b[k-1],n-b[k-1]+2);
}
cout<<ans<<'\n';
return 0;
}
祝大家学习愉快!
题解-CF1437E Make It Increasing的更多相关文章
- 【题解】Greatest Common Increasing Subsequence
[题解]Greatest Common Increasing Subsequence vj 唉,把自己当做DP入门选手来总结这道题吧,我DP实在太差了 首先是设置状态的技巧,设置状态主要就是要补充不漏 ...
- LeetCode题解之Longest Continuous Increasing Subsequence
1.题目描述 2.问题分析 从每一个num[i]往前扫描即可. 3.代码 int findLengthOfLCIS(vector<int>& nums) { ){ return n ...
- Lintcode397 Longest Increasing Continuous Subsequence solution 题解
[题目描述] Give an integer array,find the longest increasing continuous subsequence in this array. An in ...
- LeetCode题解之 Increasing Order Search Tree
1.题目描述 2/问题分析 利用中序遍历,然后重新构造树. 3.代码 TreeNode* increasingBST(TreeNode* root) { if (root == NULL) retur ...
- LeetCode题解之Longest Increasing Subsequence
1.题目描述 2.题目分析 使用动态规划,在计算以每个字符结尾的最长子序列. 3.代码 int lengthOfLIS(vector<int>& nums) { ){ ; } ve ...
- Codeforces Round #160 (Div. 1) 题解【ABCD】
Codeforces Round #160 (Div. 1) A - Maxim and Discounts 题意 给你n个折扣,m个物品,每个折扣都可以使用无限次,每次你使用第i个折扣的时候,你必须 ...
- LeetCode Longest Increasing Path in a Matrix
原题链接在这里:https://leetcode.com/problems/longest-increasing-path-in-a-matrix/ Given an integer matrix, ...
- 【题解】【数组】【查找】【Leetcode】Search in Rotated Sorted Array
Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...
- 300. Longest Increasing Subsequence
题目: Given an unsorted array of integers, find the length of longest increasing subsequence. For exam ...
随机推荐
- linux 异步I/O 信号
if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) { ngx_log_error(NGX_LOG_ALERT, cycl ...
- Golang中的OO(面向对象)
组合 > 继承 Go中的设计,以为继承的被诟病,所以Golang的设计团队在语言的设计时并没有采用经典的OO模式 那Golang中各个部分是怎么联系到一起的呢 type ReadWriter i ...
- deepin V20 简易入门指南
deepin V20 入坑指南 系统安装 入坑第一步自然是先安装系统了,deepin的安装方式很简单只需要一个U盘即可,在官网下载好安装镜像文件,使用官方的启动盘制作工具,开机时选择从U盘启动即可,安 ...
- First day,beginning!
beginning 在闲暇的时光记录当下的生活,一直是自己所期盼的: 由于种种原因(懒惰),一直未能开始,那么就从今天开始吧! 看下日期,从实习到现在一个月刚刚好: 公司很不错,师傅特别好,感觉自己是 ...
- python3处理csv文件
1. 基础语句 1.1 文件的读取 如果需要读取一行数据如下表1所示,那么需要读取域名下面的数据,便使用如下代码: with open('A.csv','rb') as csvfile: reader ...
- 使用pdfFactory为PDF文件设定查看选项
一般情况下,大部分PDF文件都会按照默认的查看设置,以100%的尺寸显示第一页的内容.但在一些特殊情况下,PDF文件的创建者会设定其他的文件查看尺寸,或设定打开页为第N页,来达到引起阅读者关注的目的. ...
- MathType中怎么编辑韩文字符
用MathType编辑公式,所涉及到符号与字母一般都是英文字母与数字,或者使用希腊字母,当然还有很多使用中文的情况.但是不仅如此,我们在使用MathType时,除了这些字符之外,还可以输入韩文或者日文 ...
- 编程小白必备——主流语言C语言知识点
对于编程语言来说,经常看到有因为各自支持的语言阵营而互怼的,其实根本没那个必要,都只是一种工具而已.当多数主流语言都会使用时也许你就不会有偏见了,本质不过都是用来描述计算机的一个任务,只是每门语言设计 ...
- zk下的kafka节点
zk从某种程度上说是kafka的单点失效组件. /brokers:里面保存了Kafk集群的所有信息,包括每台broker的注册信息,集群上所有topic的信息等. /controller:保存了Kaf ...
- CentOS下如何用nmon收集系统实时运行状况
#赋予执行权限 chmod +x nmon 执行./nmon可以查看实时的系统状态有提示的,d看磁盘,n看网络,c看cpu #如果不想看实时的,想收集系统长时间运行情况然后分析,可用这个 nohup ...