在线求调~ wa on #9,10
查看原帖
在线求调~ wa on #9,10
117307
hyj0824楼主2023/4/1 18:00
#include <cstdio>
#include <cstring>
#include <forward_list>
#include <iostream>
#include <numeric>
#include <queue>
#include <cmath>
using std::cout;
using std::cin;
#define endl '\n'
// using std::endl; // I won't use you forever!
typedef const int& cint;
typedef long long ll;
typedef const ll& cll;

cint maxl = 1e5 + 10, maxn = 1e9 + 1;

ll l, rk;
ll loge[maxl]; // 存日志
ll sum;

// 单调性分析:随着每题码量n减少,切题数量k一定会增加
// 由于函数不一定是严格单减 因此会有n的最大最小之分
// 我们二分n 找到第一个大于k的n 返回r
// 再次二分 找到第一个小于k的n 返回l

ll check_cnt(int n) {
    // 手动模拟每个日志
    ll sum = 0, cnt = 0;
    for (int i = 1; i <= l; i++) {
        sum += loge[i];
        // 更新当前的码量
        if (sum < 0)
            sum = 0;
        if (sum >= n)
            sum = 0, cnt++;
    }
    return cnt;
}

void bin(int& l, int& r, bool check(int)) {
    while (l + 1 < r) {
        int mid = (l + r) >> 1;
        if (check(mid)) {
            l = mid;
        } else {
            r = mid;
        }
    }
}

int main() {
    std::ios::sync_with_stdio(0);
    cin >> l >> rk;
    for (int i = 1; i <= l; i++) {
        cin >> loge[i];
        // 前缀和优化?
    }
    int min, max;
    // 第一个二分,求n的最小值
    // l为大于rk的n,r为小于等于rk的n
    int l = 0, r = maxn;
    bin(l, r, [](int n) { return check_cnt(n) > rk; });
    min = r;

    // 第二个二分,求n的最大值
    // l是肯定可行(l为大于等于rk的n)
    // r是肯定不可行(r为小于rk的n)
    l = 0, r = maxn;
    bin(l, r, [](int n) { return check_cnt(n) >= rk; });
    max = l;

    // 判断输出
    if (min <= max)
        cout << min << " " << max;
    else
        cout << -1;

    return 0;
}

不知道为啥过不了。。。define int long long 也不行。

2023/4/1 18:00
加载中...