QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#423527#2070. Heavy Stones_LAP_WA 3ms54192kbC++146.3kb2024-05-28 08:17:172024-05-28 08:17:18

Judging History

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

  • [2024-05-28 08:17:18]
  • 评测
  • 测评结果:WA
  • 用时:3ms
  • 内存:54192kb
  • [2024-05-28 08:17:17]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 10;
int n; long long A[N], S[N];

mt19937 Rand(chrono::steady_clock::now().time_since_epoch().count());

struct node {
    long long val, sum; int l, r, siz;
    node(long long _val = 0, long long _sum = 0, int _l = 0, int _r = 0): 
        val(_val), sum(_sum), l(_l), r(_r), siz(_r - _l + 1) {}
};
node operator + (const node &lhs, const node &rhs) {
    return node(lhs.val + rhs.siz * lhs.sum + rhs.val, lhs.sum + rhs.sum, min(lhs.l, rhs.l), max(lhs.r, rhs.r));
}
bool operator < (const node &lhs, const node &rhs) {
    if(lhs.sum * rhs.siz != lhs.siz * rhs.sum) return lhs.sum * rhs.siz < lhs.siz * rhs.sum;
    return lhs.l < rhs.l;
}
bool operator == (const node &lhs, const node &rhs) {return lhs.val == rhs.val && lhs.l == rhs.l && lhs.r == rhs.r; }
bool operator > (const node &lhs, const node &rhs) {return rhs < lhs; }
bool operator <= (const node &lhs, const node &rhs) {return lhs < rhs || lhs == rhs; }
bool operator >= (const node &lhs, const node &rhs) {return lhs > rhs || lhs == rhs; }

namespace FHQ {
    int root = 0;
    const int M = N * 6;
    int lc[M], rc[M], siz[M], len[M], tot = 0; long long sum[M], ans[M];
    unsigned int key[M]; node val[M];
    inline int New(node x) {
        ++tot; lc[tot] = rc[tot] = 0, siz[tot] = 1, key[tot] = Rand();
        sum[tot] = x.sum, ans[tot] = x.val, len[tot] = x.siz, val[tot] = x; return tot;
    }
    inline void maintain(int u) {
        siz[u] = siz[lc[u]] + siz[rc[u]] + 1; 
        len[u] = len[lc[u]] + val[u].siz + len[rc[u]];
        sum[u] = val[u].sum + sum[lc[u]] + sum[rc[u]];
        ans[u] = ans[lc[u]] + val[u].val + ans[rc[u]] + len[rc[u]] * (val[u].sum + sum[lc[u]]) + sum[lc[u]] * val[u].siz;
    }
    void dfs(int u) {
        if(lc[u]) dfs(lc[u]);
        cerr << u << ' ' << lc[u] << ' ' << rc[u] << ' ' << sum[u] << ' ' << ans[u] << ' ' << val[u].sum << ' ' << val[u].val << ' ' << val[u].l << ' ' << val[u].r << '\n';
        if(rc[u]) dfs(rc[u]);
    }
    void split(int u, node T, int &x, int &y) {
        if(!u) {x = y = 0; return; }
        if(val[u] <= T) {
            x = u; split(rc[u], T, rc[x], y);
            maintain(x);
        } else {
            y = u; split(lc[u], T, x, lc[y]);
            maintain(y);
        }
    }
    void split_rank(int u, int rnk, int &x, int &y) {
        if(!u) {x = y = 0; return; }
        if(siz[lc[u]] + 1 <= rnk) {
            x = u; split_rank(rc[u], rnk - siz[lc[u]] - 1, rc[x], y);
            maintain(x);
        } else {
            y = u; split_rank(lc[u], rnk, x, lc[y]);
            maintain(y);
        }
    } 
    int merge(int x, int y) {
        if(!x || !y) return x | y;
        if(key[x] <= key[y]) {
            rc[x] = merge(rc[x], y);
            maintain(x); return x;
        } else {
            lc[y] = merge(x, lc[y]);
            maintain(y); return y;
        }
    }
    inline void insert(int v) {
        // cerr << "FHQ Insert " << val[v].sum << ' ' << val[v].val << ' ' << val[v].l << ' ' << val[v].r << '\n';
        int x, y; split(root, val[v], x, y);
        // if(val[v].l == 1 && val[v].r == 3) {
        //     cerr << "AAA" << x << ' ' << y << ' ' << v << '\n';
        // }
        // cerr << "split to " << x << ' ' << y << '\n';
        root = merge(merge(x, v), y);
        // if(val[v].l == 1 && val[v].r == 3) {
        //     cerr << "AAA" << x << ' ' << y << '\n';
        //     dfs(root);
        // }
    }
    inline void erase(node T) {
        // if(T.l == 3 && T.r == 3) cerr << "FHQ Erase " << T.sum << ' ' << T.val << ' ' << T.l << ' ' << T.r << '\n';
        int x, y, z; split(root, T, x, z), split_rank(x, siz[x] - 1, x, y);
        // if(T.l == 3 && T.r == 3) {
        //     cerr << "x = "; dfs(x);
        //     cerr << "y = "; dfs(y);
        //     cerr << "z = "; dfs(z);
        // }
        root = merge(x, z);
    }
}

int main() {
    ios::sync_with_stdio(false), cin.tie(0);

    cin >> n;
    for(int i = 1; i <= n; i ++) 
        cin >> A[i];
    for(int i = 1; i <= n; i ++)
        S[i] = S[i - 1] + A[i];
    
    vector<node> stk; vector<pair<node, int>> pre, suf;
    for(int i = 1; i <= n; i ++) {
        node u(A[i], A[i], i, i);
        while(!stk.empty() && stk.back() <= u) {
            node T = stk.back(); stk.pop_back();
            pre.push_back({T, -1}); u = u + T;
        }
        stk.emplace_back(u), pre.push_back({u, 1});
    }
    stk.clear();
    for(int i = n; i >= 1; i --) {
        node u(A[i], A[i], i, i);
        while(!stk.empty() && stk.back() <= u) {
            node T = stk.back(); stk.pop_back();
            suf.push_back({T, -1}); u = u + T;
        }
        stk.emplace_back(u), suf.push_back({u, 1});
    }

    // for(auto x : stk) 
    //     cerr << x.sum << ' ' << x.val << ' ' << x.l << ' ' << x.r << '\n';
    // cerr << '\n';
    for(int i = 0; i < stk.size(); i ++) {
        FHQ::insert(FHQ::New(stk[i]));
        // FHQ::dfs(FHQ::root);
    }
    int pos_L = -1, pos_R = (int)suf.size() - 1;
    for(int i = 1; i <= n; i ++) {
        while(pos_R >= 0 && (suf[pos_R].first.l != i + 1 || suf[pos_R].second != 1)) {
            if(suf[pos_R].second == 1) {
                FHQ::erase(suf[pos_R].first);
                // if(i == 5) cerr << "Erase " << suf[pos_R].first.l << ' ' << suf[pos_R].first.r << '\n';
                // if(i == 5) FHQ::dfs(FHQ::root);
            } else {
                FHQ::insert(FHQ::New(suf[pos_R].first));
                // if(i == 5) cerr << "Insert " << suf[pos_R].first.l << ' ' << suf[pos_R].first.r << '\n';
                // if(i == 5) FHQ::dfs(FHQ::root);
            }
            pos_R --;
        }
        // if(i == 5) FHQ::dfs(FHQ::root);
        cout << FHQ::ans[FHQ::root] + 1ll * n * A[i] - S[n] << " \n"[i == n];
        while(pos_L == -1 || pre[pos_L].first.r != i) {
            pos_L ++;
            if(pre[pos_L].second == 1) {
                FHQ::insert(FHQ::New(pre[pos_L].first));
                // cerr << "INS " << pre[pos_L].first.l << ' ' << pre[pos_L].first.r << '\n';
            } else {
                FHQ::erase(pre[pos_L].first);
                // cerr << "DEL " << pre[pos_L].first.l << ' ' << pre[pos_L].first.r << '\n';
            }
        }
        // if(i == 4) FHQ::dfs(FHQ::root);
    }

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 3ms
memory: 54192kb

input:

5
2 1 3 5 4

output:

22 21 24 33 38

result:

wrong answer 1st lines differ - expected: '35 35 36 43 49', found: '22 21 24 33 38'