2 条题解

  • 0
    @ 2026-5-18 20:39:40

    前言:第一眼看到题在一个给定序列上加上一个等差数列就觉的和这题有点类似,但发现首项和公差均为 11 且结束点一定为 nn 便发现了有蹊跷。


    • 题意:给定数组 aa,可以在任意位置 ii 加上(或减去)一个首项为 11,公差为 11,长度为 ni+1n-i+1(即结束点为 nn)的等差数列。问需要加(或减)几个等差数列可使 aa 中的值全为 00

    此题正解应为:二阶差分

    观察到

    等差数列 1 2 3 4 5
    差分一次 1 1
    差分两次 0

    可得结论:在差分两次后的数组的 ii 位置上加 11,就等价于在原数组 iinn 上加上了一个首项为 11 公差为 11 的等差数列。

    所以,数组 aa 两次差分后所有数的绝对值的和,即为将原数列应加上等差数列的个数。

    代码如下

    #include <iostream>
    #include <cmath>
    using namespace std;
    long long n,a[200010],s[200010],s2[200010],ans;
    //别忘了long long
    int main(){
        cin>>n;
        for(int i = 1;i<=n;i++){
            cin>>a[i];
            s[i]=a[i]-a[i-1];
            s2[i]=s[i]-s[i-1];
            ans+=abs(s2[i]);
        }
        cout<<ans;
    }
    
    
    • 0
      @ 2025-10-8 17:13:45
      #include <bits/stdc++.h>
      using namespace std;
       
      using ll = long long;
       
      int main() {
          ios::sync_with_stdio(False); cin.tie(0);
         
          int n; cin >> n;
          vector<ll> a(n);
          for (int i = 0; i < n; i++) {
              cin >> a[i];
          }
         
          ll ans = 0;
          ll contribution = 0;
          ll cnt_ops = 0;
          for (int i = 0; i < n; i++) {
              contribution += cnt_ops;
              a[i] += contribution;
              
              ll cur_ops = -a[i];
              ans += abs(cur_ops);
              cnt_ops += cur_ops;
              contribution += cur_ops;
          }
          
          cout << ans << '\n';
      }
      

      • 1

      [USACO24JAN] Balancing Bacteria B【思维】

      信息

      ID
      7504
      时间
      2000ms
      内存
      256MiB
      难度
      8
      标签
      递交数
      68
      已通过
      11
      上传者