QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#535302#8712. Flooding Wallmakrav#0 1735ms97116kbC++207.2kb2024-08-27 22:56:092024-08-27 22:56:09

Judging History

This is the latest submission verdict.

  • [2024-08-27 22:56:09]
  • Judged
  • Verdict: 0
  • Time: 1735ms
  • Memory: 97116kb
  • [2024-08-27 22:56:09]
  • Submitted

answer

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

const int mod = 1e9 + 7;

#define pb push_back
#define all(x) (x).begin(), (x).end()
#define int ll

int pw2[500010];

struct node {
    int len, pr, lolpr;
    node() = default;
    node(int l_, int pr_, int lolpr_) {
        len = l_;
        pr = pr_;
        lolpr = lolpr_;
    }
};

node operator+(node a, node b) {
    if (a.len == -1) return b;
    if (b.len == -1) return a;
    int newlen = a.len + b.len;
    int newpr = (a.pr * b.pr) % mod;
    int newlol = (a.lolpr * b.pr + b.lolpr * pw2[a.len]) % mod;
    return node(newlen, newpr, newlol);
}

int mul(int a, int b) {
    return (a * b) % mod;
}

int sum(int a, int b) {
    return (a + b >= mod ? a + b - mod : a + b);
}

int diff(int a, int b) {
    return (a - b < 0 ? a - b + mod : a - b);
}

struct segtree {
    int n;
    vector<node> t;
    segtree() = default;
    segtree(int n_) {
        n = n_;
        t.resize(4 * n);
        build(1, 0, n);
    }

    void build(int v, int tl, int tr) {
        if (tl + 1 == tr) {
            t[v] = node(1, 0, 0);
            return;
        }
        int tm = (tl + tr) / 2;
        build(v * 2, tl, tm);
        build(v * 2 + 1, tm, tr);
        t[v] = t[v * 2] + t[v * 2 + 1];
    }

    void upd(int v, int tl, int tr, int p, int vl) {
        if (tl + 1 == tr) {
            t[v] = node(1, vl, vl);
            return;
        }
        int tm = (tl + tr) / 2;
        if (p < tm) upd(v * 2, tl, tm, p, vl);
        else upd(v * 2 + 1, tm, tr, p, vl);
        t[v] = t[v * 2] + t[v * 2 + 1];
    }

    node get(int v, int tl, int tr, int l, int r) {
        if (tr <= l || tl >= r) return node(-1, -1, -1);
        if (l <= tl && tr <= r) return t[v];
        int tm = (tl + tr) / 2;
        return get(v * 2, tl, tm, l, r) + get(v * 2 + 1, tm, tr, l, r);
    }
};

void solve() {
    ll n; cin >> n;
    vector<int> a(n), b(n);
    for (int i = 0; i < n; i++) {
        ll x; cin >>x;a[i]=x;
    }
    for (int i = 0; i < n; i++) {
        ll x; cin>>x;b[i]=x;
    }
    int ans = 0;
    for (int i = 0; i < n; i++) {
        ans = diff(ans, mul(sum(a[i], b[i]), pw2[n - 1]));
    }
    {
        vector<pair<int, int>> ev;
        for (int i = 0; i < n; i++) {
            ev.pb({a[i], -i});
            ev.pb({b[i], -i});
        }
        sort(all(ev));
        segtree sg(n);
        vector<int> val(n, 0);
        for (int i = 0; i < ev.size(); i++) {
            int ind = -ev[i].second;
            int prright = (ind == n - 1 ? 1 : sg.get(1, 0, n, ind + 1, n).pr);
            if (!prright) {
                val[ind]++;
                sg.upd(1, 0, n, ind, val[ind]);
                continue;
            }
            int LOL = mul(prright, pw2[ind]);
            if (ind) {
                node rs = sg.get(1, 0, n, 0, ind);
                LOL = sum(LOL, mul(prright, diff(rs.lolpr, mul(rs.pr, rs.len))));
            }
            ans = sum(ans, mul(LOL, ev[i].first));
            //cout << ind << ' ' << ev[i].first << ' ' << LOL << " add to ans\n";
            val[ind]++;
            sg.upd(1, 0, n, ind, val[ind]);
        }
        for (int i = 0; i < n; i++) sg.upd(1, 0, n, i, 0);
        val.assign(n, 0);
        for (int I = 0; I < ev.size(); I++) {
            int j = I;
            while (j < ev.size() && ev[j].first == ev[I].first) j++;
            //cout << I << ' ' << j << '\n';
            vector<int> ps;
            for (int k = I; k < j; k++) {
                ps.pb(-ev[k].second);
                val[ps.back()]++;
                sg.upd(1, 0, n, ps.back(), val[ps.back()]);
            }
            reverse(all(ps));
            vector<int> fuck_pref(ps.size() + 1), fuck_suff(ps.size() + 1);
            int cp = 1, cpov = 1, cpv = 1;
            vector<int> prs(ps.size() + 1, 1);
            for (int i = 0; i < ps.size(); i++) {
                int prv = (i == 0 ? 0 : ps[i - 1]);
                if (ps[i] - prv >= 2) {
                    prs[i] = sg.get(1, 0, n, prv + 1, ps[i]).pr;
                }
            }
            prs.back() = (ps.back() == n - 1 ? 1 : sg.get(1, 0, n, ps.back() + 1, n).pr);
            for (int i = 0; i < ps.size(); i++) {
                cp = mul(cp, prs[i]);
                cpov = mul(cpov, val[ps[i]] - 1);
                cpv = mul(cpv, val[ps[i]]);
                fuck_pref[i + 1] = mul(cp, diff(cpv, cpov));
            }
            cp = 1; cpov = 1; cpv = 1;
            for (int i = ps.size() - 1; i >= 0; i--) {
                cp = mul(cp, prs[i + 1]);
                cpov = mul(cpov, val[ps[i]] - 1);
                cpv = mul(cpv, val[ps[i]]);
                fuck_suff[ps.size() - i] = mul(cp, diff(cpv, cpov));
            }
            for (int i = 0; i < ps.size(); i++) {
                int L = (ps[i] == 0 ? 1 : sg.get(1, 0, n, 0, ps[i]).pr), R = (ps[i] == n - 1 ? 1 : sg.get(1, 0, n, ps[i] + 1, n).pr);
                int cnt_fuck1 = diff(sum(mul(L, pw2[n - ps[i] - 1]), mul(R, pw2[ps[i]])), mul(L, R));
                int cnt_fuck2 = sum(cnt_fuck1, mul(fuck_pref[i], mul(prs[i], mul(fuck_suff[ps.size() - i - 1], mul(prs[i + 1], val[ps[i]] - 1)))));
                //cout << ps[i] << ' ' << ev[I].first << ' ' << cnt_fuck2 << ' ' << cnt_fuck1 << '\n';
                ans = diff(ans, mul(cnt_fuck2, ev[I].first));
                //cout << "minuss " << cnt_fuck2 * ev[I].first << '\n';
            }
            for (int i = 0; i < ps.size() - 1; i++) {
                if (ps[i + 1] == ps[i]) assert(false);
                int lol = mul(fuck_pref[i + 1], mul(fuck_suff[ps.size() - i - 1], mul(ps[i + 1] - ps[i] - 1, mul(prs[i + 1], ev[I].first))));
                ans = diff(ans, lol);
            }
            I = j - 1;
        }
    }
    reverse(all(a));
    reverse(all(b));
    {
        //cout<<"didrev\n";
        vector<pair<int, int>> ev;
        for (int i = 0; i < n; i++) {
            ev.pb({a[i], -i});
            ev.pb({b[i], -i});
        }
        sort(all(ev));
        segtree sg(n);
        vector<int> val(n, 0);
        for (int i = 0; i < ev.size(); i++) {
            int ind = -ev[i].second;
            int prright = (ind == n - 1 ? 1 : sg.get(1, 0, n, ind + 1, n).pr);
            if (!prright) {
                val[ind]++;
                sg.upd(1, 0, n, ind, val[ind]);
                continue;
            }
            int LOL = mul(prright, pw2[ind]);
            if (ind) {
                node rs = sg.get(1, 0, n, 0, ind);
                LOL = sum(LOL, mul(prright, diff(rs.lolpr, mul(rs.pr, rs.len))));
            }
            ans = sum(ans, mul(LOL, ev[i].first));
            //cout << ind << ' ' << ev[i].first << ' ' << LOL << " add to ans\n";
            val[ind]++;
            sg.upd(1, 0, n, ind, val[ind]);
        }
    }
    cout << ans << '\n';
}

signed main() {
    pw2[0] = 1;
    for (int i = 1; i < 500010; i++) pw2[i] = (pw2[i - 1] * 2) % mod;
    ll tt = 1;
    #ifdef LOCAL 
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
        cin >> tt;
    #else 
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #endif
    while (tt--) {
        solve();
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 0
Wrong Answer

Test #1:

score: 0
Wrong Answer
time: 4ms
memory: 7464kb

input:

4
1 1 1 1
2 2 2 2

output:

999999991

result:

wrong answer 1st lines differ - expected: '6', found: '999999991'

Subtask #2:

score: 0
Wrong Answer

Test #23:

score: 0
Wrong Answer
time: 0ms
memory: 7704kb

input:

100
948 425 211 688 416 81 356 602 712 954 117 522 797 75 281 491 662 669 78 156 939 526 929 937 916 619 166 777 48 898 449 278 298 714 668 755 679 38 389 602 195 135 672 833 655 541 473 27 596 274 351 353 598 993 837 246 950 99 179 751 481 843 550 195 964 279 806 82 330 599 124 756 649 838 513 625 ...

output:

141891290

result:

wrong answer 1st lines differ - expected: '164439470', found: '141891290'

Subtask #3:

score: 0
Skipped

Dependency #2:

0%

Subtask #4:

score: 0
Skipped

Dependency #1:

0%

Subtask #5:

score: 0
Wrong Answer

Test #57:

score: 0
Wrong Answer
time: 1735ms
memory: 97116kb

input:

500000
1 1 1 1 2 2 2 1 1 1 1 1 2 2 1 1 2 2 2 2 1 2 1 1 2 1 1 1 1 2 1 2 2 1 1 2 2 2 1 1 2 2 2 2 1 2 2 2 2 1 2 2 2 1 2 2 2 1 2 2 2 2 2 2 2 2 1 1 2 1 2 1 2 2 1 2 2 2 2 2 2 2 1 1 1 2 2 2 1 1 2 1 2 2 1 2 2 1 2 2 2 1 2 2 2 2 2 2 2 2 1 1 1 2 1 2 1 1 2 1 2 1 2 2 1 1 2 1 1 1 1 1 2 2 2 2 2 2 1 2 2 1 1 2 1 2 1...

output:

934781795

result:

wrong answer 1st lines differ - expected: '869044223', found: '934781795'

Subtask #6:

score: 0
Skipped

Dependency #1:

0%