CF1853

你谷的加题速度实在太慢了

被 CF 的题目薄纱

A

可以选任意次 i[1,n],使 a[1i]++,a[i+1n]。求最少操作次数使得原数列变成非从小到大排序的。

首先判断原数列是否已经非排序。然后看每一个相邻位置 a[i],a[i+1],令 ans=min(ans,(a[i+1]a[i])÷2+1).

B

斐波那契式数列:ai=ai1+ai2,但 a1,2 不定。每项非负。

有多少个斐波那契式数列满足第 k 项是 n

Hint: Can a sequence involving n, which is up to 105, really have up to 109 terms?

其实,根据斐波那契数列的增长速度,根本到达不了 109 的项数。我们枚举数列倒数第二项 1n,倒推 k 项,看看是否满足每一项都非负。

C

1+,每次会删去这些数中的第 a1n 小的数。问:删除 k 次后,剩下的最小数是多少。

反向考虑。我们不是删除,而是在 aii 个位置后面插入数。这样的好处是我们不用看我们删完之后谁接上来,只用在一个固定的位置不断插入即可。

res 为最终最小值,这只是我们记出来方便思考。初始令一变量 ans=1,表示第 k 天后 res 的排名是 1。(最后答案前面的删完了自然是 1

考虑插入一些数回到前一天的状态,等回到第 1 天前,此时 ans 的值就是初始时 res 的位置,也就是要输出的答案。(先特判 a[1]1 则答案必为 1

在所有 aii 位置插入数,保证 aiians,因为插入到 ans 位置后面没有意义。

注意我们并不在乎插入了什么数,只需统计每次在 ans 前又插入了几个数 cnt,同时在这次结束时ansans+cnt 即可

然后在更新了 ans 时,要注意又有一些 aii 可以插入到 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();
}

D

定义长度 n 的“不平衡数组” {bn}:

  1. nbin.

  2. i,j,bi+bj0.

  3. 恰有 ai 个位置 j,使 bi+bj>0,允许 i=j.

现给定 {an}。要么指出不存在 {bn},要么构造出一组 {bn}

提示:

(n,n),(n1,(n1)),,(1,1)
每对里只能选一种。

bi>bjai>aj.

x 是使 |bi| 最大的 i。若 bx<0,则 ax=0;否则 ax=n。同时,不可能有另一个 ay=0n

所以“存在绝对值最大的 |bi|

(存在一个 ai=0) “存在一个 ai=n”。

先判断是否存在绝对值最大,然后固定此位置为绝对值最大,就可以递归处理剩余没处理的数!!!

如果在某次递归中不存在绝对值最大,说明答案不存在。

但是每次循环找 ai=0/nO(n2) 的。我们可以ai 排序。这样每次判断就是 O(1) 的了!

posted @   FLY_lai  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示