QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#282648#7616. Jump Graphlight_ink_dots#ML 2ms14072kbC++144.0kb2023-12-12 17:13:362023-12-12 17:13:37

Judging History

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

  • [2023-12-12 17:13:37]
  • 评测
  • 测评结果:ML
  • 用时:2ms
  • 内存:14072kb
  • [2023-12-12 17:13:36]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

const int maxn = 300010, maxlg = 20;
int lg[maxn], st[maxlg][maxn];
int pre[maxn], nxt[maxn];
int p[maxn], rev[maxn], n;
void solve(int, int);
long long ans[maxn];

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", p + i), rev[p[i]] = i, st[0][i] = p[i];
    for (int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;
    for (int l = 1; l <= lg[n]; l++)
        for (int i = 1; i + (1 << l) - 1 <= n; i++)
            st[l][i] = max(st[l - 1][i], st[l - 1][i + (1 << (l - 1))]);
    for (int i = 1; i <= n; i++) {
        if (p[i - 1] > p[i]) {
            pre[i] = i - 1;
            continue;
        }
        pre[i] = pre[i - 1];
        while (pre[i] && p[pre[i]] < p[i]) pre[i]--;
    }
    nxt[n + 1] = n + 1;
    for (int i = n; i; i--) {
        if (p[i + 1] > p[i]) {
            nxt[i] = i + 1;
            continue;
        }
        nxt[i] = nxt[i + 1];
        while (nxt[i] != n + 1 && p[nxt[i]] < p[i]) nxt[i]++;
    }
    solve(1, n);
    for (int i = 1; i <= n; i++) printf("%lld ", ans[i]);
    printf("\n");
    return 0;
}

int rmq(int l, int r) {
    int Lg = lg[r - l + 1];
    return max(st[Lg][l], st[Lg][r - (1 << Lg) + 1]);
}

long long c(int, int);

long long tL(const int r) {
    static unordered_map<int, long long> mp;
    if (pre[r] == 0)
        return 0;
    if (mp.count(r))
        return mp[r];
    return mp[r] = c(pre[r], r) + tL(pre[r]) - 1;
}

long long tR(const int l) {
    static unordered_map<int, long long> mp;
    if (nxt[l] == n + 1)
        return 0;
    if (mp.count(l))
        return mp[l];
    return mp[l] = c(l, nxt[l]) + tR(nxt[l]) - 1;
}

long long c(int l, int r) {
    static unordered_map<long long, long long> mp;
    if (l > r)
        return 0;
    if (l == r)
        return 1;
    long long I = 1ll * l * (n + 1) + r;
    if (mp.count(I))
        return mp[I];
    if (nxt[l] >= r && pre[r] <= l)
        return mp[I] = c(l + 1, r - 1) + r - l + 1;
    int mx = rmq(l, r), p = rev[mx];
    return mp[I] = tR(l) - tR(p) + tL(r) - tL(p) + 1;
}

long long cL(int l) {
    static unordered_map<int, long long> mp;
    if (l > n)
        return 0;
    if (mp.count(l))
        return mp[l];
    if (nxt[l] == n + 1)
        return mp[l] = cL(l + 1) + n - l + 1;
    return mp[l] = c(l + 1, nxt[l] - 1) + cL(nxt[l]) + nxt[l] - l;
}

long long cR(int r) {
    static unordered_map<int, long long> mp;
    if (!r)
        return 0;
    if (mp.count(r))
        return mp[r];
    if (pre[r] == 0)
        return mp[r] = cR(r - 1) + r;
    return mp[r] = c(pre[r] + 1, r - 1) + cR(pre[r]) + r - pre[r];
}

void s(int l, int r) {
    if (l > r)
        return;
    int mx = rmq(l, r), p = rev[mx];
    auto L = c(p, r + 1) - 1, R = c(l - 1, p) - 1;
    ans[l] += L, ans[p] -= L, ans[p + 1] += R, ans[r + 1] -= R;
    auto x = c(l - 1, p - 1) + c(p + 1, r + 1) - 2;
    ans[p] += x, ans[p + 1] -= x;
    s(l, p - 1), s(p + 1, r);
    return;
}

void sL(int r) {
    if (!r)
        return;
    int mx = rmq(1, r), p = rev[mx];
    auto L = c(p, r + 1) - 1, R = cR(p);
    ans[1] += L, ans[p] -= L, ans[p + 1] += R, ans[r + 1] -= R;
    auto x = cR(p - 1) + c(p + 1, r + 1) - 1;
    ans[p] += x, ans[p + 1] -= x;
    sL(p - 1), s(p + 1, r);
    return;
}

void sR(int l) {
    if (l == n + 1)
        return;
    int mx = rmq(l, n), p = rev[mx];
    auto L = cL(p), R = c(l - 1, p) - 1;
    ans[l] += L, ans[p] -= L, ans[p + 1] += R, ans[n + 1] -= R;
    auto x = cL(p + 1) + c(l - 1, p - 1) - 1;
    ans[p] += x, ans[p + 1] -= x;
    s(l, p - 1), sR(p + 1);
    return;
}

void solve(int l, int r) {
    int mx = rmq(l, r), p = rev[mx];
    auto L = cL(p), R = cR(p);
    ans[1] += L, ans[p] -= L, ans[p + 1] += R, ans[n + 1] -= R;
    auto x = cR(p - 1) + cL(p + 1);
    ans[p] += x, ans[p + 1] -= x;
    sL(p - 1), sR(p + 1);
    for (int i = 1; i <= n; i++) ans[i] += ans[i - 1];
    return;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 10056kb

input:

6
1 6 3 2 5 4

output:

11 7 7 7 6 8 

result:

ok single line: '11 7 7 7 6 8 '

Test #2:

score: 0
Accepted
time: 2ms
memory: 12080kb

input:

2
1 2

output:

1 1 

result:

ok single line: '1 1 '

Test #3:

score: 0
Accepted
time: 2ms
memory: 14072kb

input:

36
9 29 1 3 14 31 24 21 10 18 22 16 8 7 15 12 17 19 25 28 27 34 11 6 32 4 20 13 2 35 23 26 33 36 30 5

output:

92 89 90 90 91 78 73 71 71 71 65 65 64 64 63 65 65 70 74 85 95 91 111 111 109 111 110 110 110 107 136 136 137 136 168 168 

result:

ok single line: '92 89 90 90 91 78 73 71 71 71 ...10 107 136 136 137 136 168 168 '

Test #4:

score: -100
Memory Limit Exceeded

input:

63
30 17 34 8 29 57 2 62 35 27 24 22 54 53 60 37 31 19 1 5 20 14 3 36 38 40 56 39 50 32 51 9 15 52 55 45 63 41 6 47 23 7 33 10 26 61 16 58 43 42 44 48 28 12 49 11 59 4 21 25 46 13 18

output:


result: