CF1853
你谷的加题速度实在太慢了
被 CF 的题目薄纱
可以选任意次 \(i\in [1,n]\),使 \(a[1\sim i]++,a[i+1\sim n]--\)。求最少操作次数使得原数列变成非从小到大排序的。
首先判断原数列是否已经非排序。然后看每一个相邻位置 \(a[i],a[i+1]\),令 \(ans=\min(ans,(a[i+1]-a[i])\div2+1).\)
斐波那契式数列:\(a_i=a_{i-1}+a_{i-2}\),但 \(a_{1,2}\) 不定。每项非负。
有多少个斐波那契式数列满足第 \(k\) 项是 \(n\)。
Hint: Can a sequence involving \(n\), which is up to \(10^5\), really have up to \(10^9\) terms?
其实,根据斐波那契数列的增长速度,根本到达不了 \(10^9\) 的项数。我们枚举数列倒数第二项 \(1\sim n\),倒推 \(k\) 项,看看是否满足每一项都非负。
\(1\sim +\infty\),每次会删去这些数中的第 \(a_{1\sim n}\) 小的数。问:删除 \(k\) 次后,剩下的最小数是多少。
反向考虑。我们不是删除,而是在 \(a_i-i\) 个位置后面插入数。这样的好处是我们不用看我们删完之后谁接上来,只用在一个固定的位置不断插入即可。
记 \(res\) 为最终最小值,这只是我们记出来方便思考。初始令一变量 \(ans=1\),表示第 \(k\) 天后 \(res\) 的排名是 \(1\)。(最后答案前面的删完了自然是 \(1\))
考虑插入一些数回到前一天的状态,等回到第 \(1\) 天前,此时 \(ans\) 的值就是初始时 \(res\) 的位置,也就是要输出的答案。(先特判 \(a[1]\ne1\) 则答案必为 \(1\))
在所有 \(a_i-i\) 位置插入数,保证 \(a_i-i\le ans\),因为插入到 \(ans\) 位置后面没有意义。
注意我们并不在乎插入了什么数,只需统计每次在 \(ans\) 前又插入了几个数 \(cnt\),同时在这次结束时\(ans\leftarrow ans+cnt\) 即可。
然后在更新了 \(ans\) 时,要注意又有一些 \(a_i-i\) 可以插入到 \(ans\) 前面了,同步更新。
解释一下 CF 官方代码。
#include <bits/stdc++.h>
using namespace std;
int n, k, a[200010];
void solve() {
cin >> n >> k;
for (int i = 0; i < n; i++) {
cin >> a[i];
a[i] -= i; //是在a[i]-i位置插入,而非a[i]
}
if (a[0] != 1) { //特判
cout << 1 << "\n";
return;
}
a[n] = 2e9; //边界守卫
long long ans = 1; //答案
int inc = 1; //inc表示本次插入会在ans前插入多少个
while (inc < n) {
int days = (a[inc] - ans + inc - 1) / inc;
//插入1次不能让下一个a[i]-i排到ans前
//一次性加很多次,跳到下一个a[i]-i也排前,优化
if (days >= k){
//如果要下一个a[i]-i排前
//已经超过剩余插入次数,就结束
ans += k * inc;
//那还能插入(剩余次数)*(插入个数)个
k = 0;
break;
}
ans += days * inc;
//插入了(插入次数)*(多少个插入位置在ans前)
k -= days;//减少剩余插入次数
while (a[inc] <= ans) inc++;
//拓展在ans前的个数
}
ans += 1ll * k * n;
//1.上面没等到inc>=n就没有了剩余次数,k=0无影响
//2.inc=n出来的,剩下k次每次都插入n个
cout << ans << "\n";//输出
}
int main() {
ios::sync_with_stdio(0);
cin.tie(nullptr);
int t;
cin >> t;
while (t--)
solve();
}
定义长度 \(n\) 的“不平衡数组” \(\{b_n\}\):
\(-n\le b_i\le n.\)
\(\forall i,j,b_i+b_j\ne 0.\)
恰有 \(a_i\) 个位置 \(j\),使 \(b_i+b_j>0\),允许 \(i=j\).
现给定 \(\{a_n\}\)。要么指出不存在 \(\{b_n\}\),要么构造出一组 \(\{b_n\}\)。
提示:
\((n,-n),(n-1,-(n-1)),\dots,(1,-1)\)。
每对里只能选一种。
\(b_i>b_j\iff a_i>a_j.\)
设 \(x\) 是使 \(|b_i|\) 最大的 \(i\)。若 \(b_x<0\),则 \(a_x=0\);否则 \(a_x=n\)。同时,不可能有另一个 \(a_y=0\) 或 \(n\)。
所以“存在绝对值最大的 \(|b_i|\)” $\iff $
“\((\)存在一个 \(a_i=0)\)”\(\bigoplus\) “存在一个 \(a_i=n\)”。
先判断是否存在绝对值最大,然后固定此位置为绝对值最大,就可以递归处理剩余没处理的数!!!
如果在某次递归中不存在绝对值最大,说明答案不存在。
但是每次循环找 \(a_i=0/n\) 是 \(O(n^2)\) 的。我们可以将 \(a_i\) 排序。这样每次判断就是 \(O(1)\) 的了!
随机推荐
- Vue第一篇 ES6的常用语法
01-变量的定义 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- Skywalking 搭建 nacos 注册中心及mysql 存储的集群架构
本文为博主原创,未经允许不得转载 Skywalking 集群是将skywalking oap作为一个服务注册到nacos上,只要skywalking oap服务没有全部宕机,保证有一个skywalki ...
- idea导入maven项目结构不全
本文为博主原创,转载请注明出处 将本地的项目导入idea中,其操作第一步为: File->open->选中导入maven项目的pom文件,正常情况通过该步骤项目就会导入到idea中. 通过 ...
- Git-历史版本切换-log-reset
- Go-获取指定长度随机字符串
// GetCode 获取一个随机用户唯一编号 func GetCode(codeLen int) string { // 1. 定义原始字符串 rawStr := "abcdefghijk ...
- 百度网盘(百度云)SVIP超级会员共享账号每日更新(2023.12.1)
一.百度网盘SVIP超级会员共享账号 可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答. 我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免 ...
- [转帖]003、体系结构之TiKV持久化
TiKV架构和作用 数据持久化 分布式一致性 MVCC 分布式事务 Coprocessor coprocessor : 协同处理器. 可以将一些SQL计算交给TiKV处理.不需要将TiKV所有数据通过 ...
- [转帖]20个常用的Linux工具命令
https://www.cnblogs.com/codelogs/p/16060113.html 简介# 网上有很多辅助开发的小工具,如base64,md5之类的,但这些小工具其实基本都可以用Linu ...
- export default 和 export 这两种方式导出的区别
参考地址 https://blog.csdn.net/sleepwalker_1992/article/details/81461543 使用export向外暴露的成员,只能使用{ }的形式来接收,这 ...
- JS 逆向之 Hook,吃着火锅唱着歌,突然就被麻匪劫了!
关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶.JS/安卓逆向等技术干货! 什么是 Hook? Hook 中文译为钩子,Hook 实际上是 Windows 中提供的一种用以 ...