QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#17206#1241. RaidChenguanlinRE 0ms0kbC++202.3kb2022-01-05 10:36:362022-05-04 13:44:35

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-05-04 13:44:35]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2022-01-05 10:36:36]
  • 提交

answer

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
constexpr int N = 40;
struct Data {
    int min;
    long long cnt;
    Data(int min = 999, long long cnt = 0) : min(min), cnt(cnt) {}
    Data &operator+=(const Data &rhs) {
        if (rhs.min < min) {
            min = rhs.min;
            cnt = rhs.cnt;
        } else if (rhs.min == min) {
            cnt += rhs.cnt;
        }

        return *this;
    }
};
int n;
std::vector<int> a, pos, pw, cnt, nxt;
std::vector<Data> dp, f;
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cin >> n;
    a.resize(n);

    for (int i = 0; i < n; ++i)
        std::cin >> a[i];

    dp = {Data(0, 1)};
    pos.resize(n + 2);
    std::iota(pos.begin(), pos.end(), -1);

    for (int i = 0; i < n; ++i) {
        std::swap(dp, f);
        pw.resize(n - i + 2);
        pw[0] = 1;

        for (int j = 1; j <= n - i + 1; ++j)
            pw[j] = pw[j - 1] * (pos[j] - pos[j - 1]);

        nxt.resize(n - i + 2);

        for (int i = n - i; i >= 0; --i) {
            if (pw[i] != pw[i + 1]) {
                nxt[i] = i + 1;
            } else {
                nxt[i] = nxt[i + 1];
            }
        }

        int p = std::lower_bound(pos.begin(), pos.end(), n - a[i]) - pos.begin();
        int upperTot = pw.back() / pw[p + 1], lTot = pos[p] - pos[p - 1], rTot = pos[p + 1] - pos[p];
        int newUpperV = pw[p - 1] * (pos[p + 1] - pos[p - 1]);
        dp.assign(newUpperV * upperTot, Data());
        cnt.resize(pw[p]);
        cnt[0] = 0;

        for (int i = 1, c = 0; i < pw[p]; ++i) {
            ++c;

            for (int j = nxt[0]; i % pw[j] == 0; j = nxt[j])
                c -= pos[j] - pos[j - 1] - 1;

            cnt[i] = c;
        }

        for (int upper = 0, s = 0, v = 0; upper < upperTot; ++upper, v += newUpperV) {
            for (int r = 0, v1 = v; r < rTot; ++r, v1 += pw[p - 1]) {
                for (int lower = 0, t = v1; lower < pw[p]; ++lower, ++s, ++t) {
                    dp[t] += f[s];
                    dp[t + pw[p - 1]] += Data(f[s].min + cnt[lower], f[s].cnt);
                }
            }
        }

        pos.erase(pos.begin() + p);
    }

    for (int i = 1; i <= n; ++i)
        std::cout << dp[i].min << " " << dp[i].cnt << "\n";

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Runtime Error

input:

5
5 3 1 4 2

output:


result: