K-Anonymous Sequence
给出一个递增的长度为n的序列\(\{a_i\}\),现在你可以进行一次操作,选择若干个数,分别减少任意一个正整数,定义权值为这些正整数之和,询问操作使得新序列的任意一个数都至少有k个数与之相同的最小权值,\(2 ≤ n ≤ 500000,2 ≤ k ≤ n,a_i\in[0,500000]\)。
解
就算题目没有告诉你序列是递增的,你也要想到排序,因为顺序对结果没有影响,从简单到困难的思想,我们对于第1个数而言,必然是相邻的数降到这个数,而且必须降到这个数,对于最终方案,必然也是降到几个旧序列中有的数(否则肯定不优),而且降的数都是相邻的,发现区间性,类似区间划分模型,设\(f[i][j]\)表示前j个数划分成i个区间的最小权值之和,(其中s为a的前缀和)我们有递推方程
\(f[i][j]=\min_{0\leq k<j}\{f[i-1][k]+\sum_{l=k+1}^j(a_l-a_{k+1})\}\)
其斜率优化式为
\(ja_{k+1}+f[i][j]-s_j=f[i-1][k]-s_k+ka_{k+1}\)
决策点集\((a_{k+1},f[i-1][k]-s_k+ka_{k+1})\)横坐标单调递增,斜率\(j\)单调递增,于是我们只要用单调队列维护下凸壳,让队首成为答案即可,时间复杂度显然\(O(n)\)。
参考代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#define il inline
#define ri register
#define Size 500050
#define ll long long
using namespace std;int T[Size],L,R;
ll dp[Size],sa[Size],y[Size],a[Size];
template<class free>il void read(free&);
int main(){int t,n,k;read(t);
while(t--){
memset(sa,0,sizeof(sa)),memset(a,0,sizeof(a)),read(n),read(k);
for(int i(1);i<=n;++i)
read(a[i]),sa[i]=sa[i-1]+a[i],dp[i]=1e11;L=R=1;
for(int i(1);i<=k;++i)y[i]=dp[i]-sa[i]+i*a[i+1];
for(int i(k);i<=n;++i){
while(L<R&&i*(a[T[L+1]+1]-a[T[L]+1])>=(y[T[L+1]]-y[T[L]]))++L;
dp[i]=dp[T[L]]+sa[i]-sa[T[L]]-(i-T[L])*a[T[L]+1],y[i]=dp[i]-sa[i]+i*a[i+1];
while(L<R&&(y[T[R]]-y[T[R-1]])*(a[i-k+2]-a[T[R]+1])
>=(y[i-k+1]-y[T[R]])*(a[T[R]+1]-a[T[R-1]+1]))--R;T[++R]=i-k+1;
}printf("%lld\n",dp[n]);
}return 0;
}template<class free>
il void read(free &x){
x&=0;ri char c;while(c=getchar(),c<'0'||c>'9');
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
}
K-Anonymous Sequence的更多相关文章
- 【dfs】Sequence Decoding
Sequence Decoding 题目描述 The amino acids in proteins are classified into two types of elements, hydrop ...
- Gym 100703G---Game of numbers(DP)
题目链接 http://vjudge.net/contest/132391#problem/G Description standard input/outputStatements — It' s ...
- 转:Python获取随机数(中文)
下面介绍下random中常见的函数. 前提:需要导入random模块 >>>import random 1.random.random random.random() 用于生成一个0 ...
- Qt4--加密日记本(子例化QMainWindow文本加密解密)
近来刚学习Qt4编程,想找个实例练习练习,于是产生了一个想法,就是怎么样做一个文本加密,这样,自己保存的一些文档可以通过软件 生成加密文本,到时候要看的时候,通过自己的软件读取就可以.既然有想法了,那 ...
- python随机数
前提:需要导入random模块 >>>import random 1.random.random random.random()用于生成一个0到1的随机符小数: 0 <= n ...
- 关于python 模块导入
如何将自己写的库加入到python的库路径中: 首先查看python包含的库路径,步骤如下: a.打开python命令界面 b.import sys c.sys.path 1.在python安 ...
- 剑指Offer 23. 二叉搜索树的后序遍历序列 (二叉搜索树)
题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 题目地址 https://www.nowcoder ...
- 开发笔记:python与随机数(转)
这些天需要用到从一堆数中随机提取几个数,于是重新研究了下random模块. 下面介绍下random中常见的函数. 前提:需要导入random模块 >>>import random 1 ...
- Leetcode 413. Arithmetic Slice 算术序列切片(动态规划,暴力)
Leetcode 413. Arithmetic Slice 算术序列切片(动态规划,暴力) 题目描述 如果一个数组1.至少三个元素2.两两之间差值相同,那么这个数组就是算术序列 比如下面的数组都是算 ...
- python随机数的产生
导入 random模块 >>> import random 1. random.random random.random()用于生成一个0到1的随机浮点数: 0 <= n ...
随机推荐
- 高级UI晋升之View渲染机制(二)
更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 优化性能一般从渲染,运算与内存,电量三个方面进行,今天开始说聊一聊Android ...
- Linux初学习之 rm 命令
现在我们来仔细的学习一下linux的rm命令,这个命令顾名思义(我猜的,嘻嘻,是remove) 命令格式: rm [OPTION]... FILE... Remove (unlink) the FIL ...
- Vue双向数据绑定原理深度解析
首先,什么是双向数据绑定?Vue是三大MVVM框架之一,数据绑定简单来说,就是当数据发生变化时,相应的视图会进行更新,当视图更新时,数据也会跟着变化. 在分析其原理和代码的时候,大家首先了解如下几个j ...
- Ubuntu 常用软件记录【持续更新】
主机之间通信 Shell 管理器: asbru-cm 文件传输工具: filezilla 虚拟化 Virtual box
- dev 中 字符串转中文拼音缩写,对grid列表进行模糊匹配,grid获取焦点行,gridlookupedit控件用拼音模糊匹配下拉选项
番外篇:. //该方法是将字符串转化为中文拼音的首写字母大写, public static string RemoveSpecialCharacters(string str){try{if (str ...
- Boost.Interprocess
https://github.com/svebert/InterprocessMsg 好像消息队列
- 带你彻底理解RSA算法原理,很简单的
1. 什么是RSA RSA算法是现今使用最广泛的公钥密码算法,也是号称地球上最安全的加密算法. 在了解RSA算法之前,先熟悉下几个术语 根据密钥的使用方法,可以将密码分为 对称密码 和 公钥密码 对称 ...
- Algo: Binary search
二分查找的基本写法: #include <vector> #include <iostream> int binarySearch(std::vector<int> ...
- react 使用触摸事件
react开发支持的事件中,onClick事件,部分标签不支持点击,只能onTouchEnd,但是在移动端,手指触碰到事件绑定元素上,滑动,也会触发该事件,故来share解决办法,有更好的方法,欢迎评 ...
- Change myself to be better
发现和改变自己不好的习惯 遇到问题的反应 自己遇到问题的时候,特别是不熟悉的问题的时候就会有点焦虑,这个应该是每个人都会有的,遇到自己不熟悉的或者是没有经历过的东西都会 感觉不舒服,或者是遇到难题或者 ...