Codeforces Global Round 13 C

Codeforces Global Round 13 C

大意

略...

思路

首先想到,如果一直贪心选择第一个数,可以得到最优解,证明如下:

考虑第k位的数 (a_k) , 在将其变为1的过程中,所有 (k+2)(k+a_k) 的数都会被免费遍历到一次。

也就是说,无论顺序如何,只要最后整个数组全为1, 那么对于每一个数 (a_i) ,再将其变为1的过程中, (i+2)(i+a_i) 一定都会被免费遍历一次。

容易发现,每一个位置的免费遍历的次数的最大值是确定的,而当我们贪心选择时,总能让所有位置达到最大值。

因为免费遍历的位置只能在选择消减的数之后,所以我们贪心将 (a_1) 变为1,然后,再贪心于 (a_1) 就相当于选择了 (a_2) ,此时 (a_2) 的免费遍历次数显然最大,归纳易得上述发现。

考虑如何求解。

对于第k位的数 (a_k) ,假设已知其免费遍历次数为 (c) ,那么会有如下三种情况:

  1. (2 leq a_k - c)

    此时,经过免费遍历后 (a_k > 1) 所以还需 (a_k-c-1) 次才能使其变为1。

    同时 (k+2)(k+a_k) 的数都会被免费遍历一次。

  2. (a_k -c = 1)

    此时,(a_k) 正好变为1

  3. (a_k - c < 1)

    这种情况比较特殊,

    (a_k) 的免费遍历次数超过了本身的值。

    观察题意会发现,超过的次数会转移到 (k+1) 位。

代码

时间复杂度 (Theta(NlogN))

我是直接复制的树状数组模板,因为是按顺序访问并添加,可以换成手写差分,于是时间复杂度 (Theta(N))

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define ll long long
#define ull unsigned long long
#define cint const int&
#define Pi acos(-1)

const int mod = 1e9+7;
const int inf_int = 0x7fffffff;
const ll inf_ll = 0x7fffffffffffffff;
const double ept = 1e-9;

int t;
int n;
int a[5050];
int r[5050];

int lowbit(cint x) { return x&-x; }

void add_p(int loc, cint num) {
    while(loc <= n) {
        r[loc] += num;
        loc = loc + lowbit(loc);
    }
}

int get_r(int x) {
    // 1~x
    int ans = 0;
    while(x) {
        ans += r[x];
        x -= lowbit(x);
    }
    return ans;
}

int main() {
    cin >> t;
    while(t--) {
        cin >> n;
        for(int i=1; i<=n; i++) cin >> a[i], r[i] = 0;
        ll ans = 0;
        for(int i=1; i<=n; i++) {
            int s = get_r(i);
            // cout << i << ' ' << a[i] << ' ' << s << endl;
            if(a[i] - s >= 1) {
                ans += a[i]-s-1;
            } else {
                add_p(i+1, s-a[i]+1);
                add_p(i+2, -(s-a[i]+1));
            }
            add_p(i+2, 1);
            add_p(min(n+1, i+a[i]+1), -1);
        }
        cout << ans << endl;
    }
    return 0;
}

45min, -4

原文地址:https://www.cnblogs.com/ullio/p/14495010.html