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)\) 的了!
随机推荐
- 媒体查询常用 - 移动端和PC端尺寸
/* 移动端 */ @media all and (max-width: 768px) { } /* PC端 */ @media all and (min-width: 769px) { }
- [java] - 获取上传到服务器上的文件路径
request.getSession().getServletContext().getRealPath("upload/" );
- udp编程及udp常见问题处理
前言 UDP协议是User Datagram Protocol的缩写,它是无连接,不可靠的网络协议.一般使用它进行实时性数据的传输,主要是因为它快,但因为它是不可靠的一种传输协议,所以不可避免的会出现 ...
- Oracle12c新增max_idle_time参数的学习与感触
Oracle12c新增max_idle_time参数的学习与感触 TLDR 其实任何软件出了新版本.readme 是很重要的. 尤其是数据库, 涉及到底层问题的. 比如这次遇到的Oracle的max_ ...
- [转帖]python字符串如何删除后几位
https://www.python51.com/jc/15070.html 1.首先在jupyter notebook中新建一个空白的python文件: 2.然后定义一个字符串,用字符串截取的方式打 ...
- [转帖]kubernetes Flannel网络剖析
https://plantegg.github.io/2022/01/19/kubernetes_Flannel%E7%BD%91%E7%BB%9C%E5%89%96%E6%9E%90/ cni(Co ...
- CentOS确认网口是否插入网线的办法
最近公司的机器存在网络问题, 部分网络总是不通, 比较奇怪. 最近一直想处理好. 第一步: 先查看网口的设备信息 可以使用 ip link show 可以讲网口信息都展示出来. 一般情况下 NO-C ...
- Whisper对于中文语音识别与转写中文文本优化的实践(Python3.10)
阿里的FunAsr对Whisper中文领域的转写能力造成了一定的挑战,但实际上,Whisper的使用者完全可以针对中文的语音做一些优化的措施,换句话说,Whisper的"默认"形态 ...
- vue3中watch监听不是你想的那样简单
vue3 中watch监听数组,数组变化后未触发回调 今天发生了一个很神奇的现象,就是我使用watch监听数组时. 被监听的数组已经发生了变化.但是没有触发回调操作. 当时的我感到很疑惑? 不应该呀? ...
- Python获取内存、CPU利用率,CPU温度
最近一个项目的需求,在软件上加入硬件实时信息,大概搜索一下,没太好的结果,所以决定自己写一篇 我的代码不难发现,都使用了psutil包,为什么呢,别的包我没太关注,纯粹是这台机的环境上有这个包 如果大 ...