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)\) 的了!
随机推荐
- HTTP 及 http 请求解析过程
本文为博主原创,未经允许不得转载: HTTP 全称为:超文本传输协议(HyperText Transfer Protocol,HTTP),一种无状态的,以请求/应答方式运行的协议, 它使用可扩展的语义 ...
- 带你熟悉NLP预训练模型:BERT
本文分享自华为云社区<[昇思技术公开课笔记-大模型]Bert理论知识>,作者: JeffDing. NLP中的预训练模型 语言模型演变经历的几个阶段 word2vec/Glove将离散的文 ...
- 完美:C# Blazor中显示Markdown并添加代码高亮
昨天发了一篇介绍这个库:C# Blazor中显示Markdown文件,介绍怎么在Blazor中显示Markdown内容的文章,文章内的代码是没有高亮的,思来相去,还是要做好,于是百度到这篇文章.NET ...
- 08-逻辑仿真工具VCS-mismatch
逻辑仿真工具VCS mismatch,预计的仿真结果和实际仿真结果不同,寻找原因? 首先考虑代码,,不要让代码跑到工具的盲区中 其次考虑仿真工具的问题 +race -- 将竞争冒险的情况写到文件中 不 ...
- NSSCTF Round#11 Basic 密码个人赛复盘
[NSSRound#11 Basic]ez_enc ABAABBBAABABAABBABABAABBABAAAABBABABABAAABAAABBAABBBBABBABBABBABABABAABBAA ...
- SpringBoot02:运行原理初探
@EnableAutoConfiguration @EnableAutoConfiguration:开启自动配置功能 以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 @Ena ...
- 百度网盘(百度云)SVIP超级会员共享账号每日更新(2023.11.25)
来给大家伙送福利了! 一.百度网盘SVIP超级会员共享账号 可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答. 我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘, ...
- 【详解配置文件系列】es7配置文件详解
首发博客地址 系列文章地址 配置文件 # ---------------------------------- Cluster ----------------------------------- ...
- [转帖]Linux cut命令
https://www.runoob.com/linux/linux-comm-cut.html#:~:text=Linux%20cut%E5%91%BD%E4%BB%A4%201%20-b%20%E ...
- Redis命令监控与简单分析
Redis命令监控与简单分析 前言 为了能够快速识别分析redis的命令 自己在环境上面进行了一些简单的跟踪以及脚本 这里不全是进行metrics, 细致到具体的命令分析 脚本部分-1 mkdir - ...