QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#577054#8546. Min or Max 2ucup-team4435#WA 204ms3644kbC++209.7kb2024-09-20 00:50:382024-09-20 00:50:39

Judging History

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

  • [2024-09-20 00:50:39]
  • 评测
  • 测评结果:WA
  • 用时:204ms
  • 内存:3644kb
  • [2024-09-20 00:50:38]
  • 提交

answer

#pragma GCC optimize("Ofast")

#include "bits/stdc++.h"

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i < (n); ++i)
#define rep1n(i, n) for (int i = 1; i <= (n); ++i)
#define repr(i, n) for (int i = (n) - 1; i >= 0; --i)
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define each(x, a) for (auto &x : a)
#define ar array
#define vec vector
#define range(i, n) rep(i, n)

using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using str = string;
using pi = pair<int, int>;
using pl = pair<ll, ll>;

using vi = vector<int>;
using vl = vector<ll>;
using vpi = vector<pair<int, int>>;
using vvi = vector<vi>;

int Bit(int mask, int b) { return (mask >> b) & 1; }

template<class T>
bool ckmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
bool ckmax(T &a, const T &b) {
    if (b > a) {
        a = b;
        return true;
    }
    return false;
}

// [l, r)
template<typename T, typename F>
T FindFirstTrue(T l, T r, const F &predicat) {
    --l;
    while (r - l > 1) {
        T mid = l + (r - l) / 2;
        if (predicat(mid)) {
            r = mid;
        } else {
            l = mid;
        }
    }
    return r;
}


template<typename T, typename F>
T FindLastFalse(T l, T r, const F &predicat) {
    return FindFirstTrue(l, r, predicat) - 1;
}

const ll INF = 2e18;
const int INFi = 1e9;
const int N = 2e5 + 5;
const int LG = 20;

template<typename node>
class segtree {
private:
    void build(int v, int vl, int vr) {
        if (vr - vl <= 1)
            return;

        int vm = (vl + vr) >> 1;
        build(v << 1, vl, vm);
        build(v << 1 | 1, vm, vr);
        tree[v] = node::merge(tree[v << 1], tree[v << 1 | 1]);
    }

    template<typename T>
    void build(int v, int vl, int vr, const std::vector<T> &arr) {
        if (vl == vr)
            return;

        if (vr - vl == 1) {
            tree[v] = node(arr[vl]);
            return;
        }

        int vm = (vl + vr) >> 1;
        build(v << 1, vl, vm, arr);
        build(v << 1 | 1, vm, vr, arr);
        tree[v] = node::merge(tree[v << 1], tree[v << 1 | 1]);
    }

    template<typename... Args>
    void _update(int v, int vl, int vr, int l, int r, Args &&... args) {
        if (r <= vl || vr <= l)
            return;

        if (l <= vl && vr <= r) {
            tree[v].apply(std::forward<Args>(args)..., vl, vr);
            return;
        }

        int vm = (vl + vr) >> 1;
        tree[v].push(tree[v << 1], vl, vr, vl, vm);
        tree[v].push(tree[v << 1 | 1], vl, vr, vm, vr);
        tree[v].clear_after_push();

        _update(v << 1, vl, vm, l, r, std::forward<Args>(args)...);
        _update(v << 1 | 1, vm, vr, l, r, std::forward<Args>(args)...);
        tree[v] = node::merge(tree[v << 1], tree[v << 1 | 1]);
    }

    node _query(int v, int vl, int vr, int l, int r) {
        if (l <= vl && vr <= r)
            return tree[v];

        int vm = (vl + vr) >> 1;
        tree[v].push(tree[v << 1], vl, vr, vl, vm);
        tree[v].push(tree[v << 1 | 1], vl, vr, vm, vr);
        tree[v].clear_after_push();

        if (r <= vm)
            return _query(v << 1, vl, vm, l, r);

        if (vm <= l)
            return _query(v << 1 | 1, vm, vr, l, r);

        return node::merge(_query(v << 1, vl, vm, l, r), _query(v << 1 | 1, vm, vr, l, r));
    }

    template<typename T>
    int _find_first(int v, int vl, int vr, int from, const T &checker) {
        if (vr <= from)
            return n;

        if (from <= vl && !checker(tree[v], vl, vr))
            return n;

        if (vr - vl == 1)
            return vl;

        int vm = (vl + vr) >> 1;
        tree[v].push(tree[v << 1], vl, vr, vl, vm);
        tree[v].push(tree[v << 1 | 1], vl, vr, vm, vr);
        tree[v].clear_after_push();

        int res = _find_first(v << 1, vl, vm, from, checker);
        return res == n ? _find_first(v << 1 | 1, vm, vr, from, checker) : res;
    }

    template<typename T>
    int _find_last(int v, int vl, int vr, int from, const T &checker) {
        if (from <= vl)
            return -1;

        if (vr <= from && !checker(tree[v], vl, vr))
            return -1;

        if (vr - vl == 1)
            return vl;

        int vm = (vl + vr) >> 1;
        tree[v].push(tree[v << 1], vl, vr, vl, vm);
        tree[v].push(tree[v << 1 | 1], vl, vr, vm, vr);
        tree[v].clear_after_push();

        int res = _find_last(v << 1 | 1, vm, vr, from, checker);
        return res == -1 ? _find_last(v << 1, vl, vm, from, checker) : res;
    }

public:
    int n;
    std::vector<node> tree;

    segtree(int n) : n(n), tree(4 * n, node()) {
        build(1, 0, n);
    }

    template<typename T>
    segtree(const std::vector<T> &arr) : n(arr.size()), tree(4 * n) {
        build(1, 0, n, arr);
    }

    int size() const {
        return n;
    }

    /*
     * update on interval [l, r)
     */
    template<typename... Args>
    void update(int l, int r, Args &&... args) {
        if (r <= l)
            return;

        _update(1, 0, n, l, r, std::forward<Args>(args)...);
    }

    /*
     * query on interval [l, r)
     */
    node query(int l, int r) {
        assert(std::max(0, l) < std::min(n, r)); // or return node() in this case
        return _query(1, 0, n, l, r);
    }

    /*
     * trying to find on interval [from, n)
     * returns n if not found
     */
    template<typename T>
    int find_first(int from, const T &checker) {
        return _find_first(1, 0, n, from, checker);
    }

    /*
     * trying to find on interval [0, from)
     * returns -1 if not found
     */
    template<typename T>
    int find_last(int from, const T &checker) {
        return _find_last(1, 0, n, from, checker);
    }
};

/*
struct node {
    node() {}
    void apply(..., int vl, int vr) {}
    void push(node &child, int vl, int vr, int cl, int cr) {}
    void clear_after_push() {}
    static node merge(const node &left, const node &right) {}
};
*/

struct node {
    ll mx, mn;
    ll mod_l, mod_r;

    node(ll x = INF, ll y = -INF) : mn(x), mx(y), mod_l(-INF), mod_r(INF) {}

    void apply(ll lq, ll rq, ll tp, int vl, int vr) {
        if (!tp) {
            assert(vl + 1 == vr);
            mod_l = -INF;
            mod_r = INF;
            mn = lq;
            mx = rq;
            return;
        }
        mod_l = max(lq, min(mod_l, rq));
        mod_r = max(lq, min(mod_r, rq));
        mn = max(lq, min(mn, rq));
        mx = max(lq, min(mx, rq));
        assert(mod_l <= mod_r);
    }

    void push(node &child, int vl, int vr, int cl, int cr) {
        if (mod_l != -INF || mod_r != INF) child.apply(mod_l, mod_r, 1, cl, cr);
    }

    void clear_after_push() {
        mod_l = -INF;
        mod_r = INF;
    }

    static node merge(const node &left, const node &right) {
        node res;
        res.mn = min(left.mn, right.mn);
        res.mx = max(left.mx, right.mx);
        return res;
    }
};

void solve() {
    int n;
    cin >> n;
    vi a(n), b(n);
    rep(i, n) {
        cin >> a[i];
        a[i]--;
    }
    rep(i, n) {
        cin >> b[i];
        b[i]--;
    }
    vl ans(n);
    vi took(n);
    rep(rot, 2) {
        vi qa(n), qb(n);
        rep(i, n) qa[a[i]] = i;
        rep(i, n) qb[b[i]] = i;
        segtree<node> st(n);
        st.update(a[0], a[0] + 1, b[0], b[0], 0);
        ll L = a[0], R = a[0];
        for (int i = 1; i < n; ++i) {
            ll x = a[i];
            ll y = b[i];
            // i > x, max= y
            // i < x, min= y
            ll min_cur = INF;
            ll max_cur = -INF;
            R = max(R, x);
            L = min(L, x);

            if (x + 1 < n) {
                if (R > x) {
                    ll val = st.query(x + 1, n).mn;
                    if (val != INF) ckmin(min_cur, min(y, val));
                }

                if (R > x) {
                    ll val = st.query(x + 1, n).mx;
                    if (val != -INF) ckmax(max_cur, min(y, val));
                }
                st.update(x + 1, n, y, INF, 1);
            }
            if (x > 0) {
                if (L < x) {
                    ll val = st.query(0, x).mn;
                    if (val != INF) ckmin(min_cur, max(y, val));
                }


                if (L < x) {
                    ll val = st.query(0, x).mx;
                    if (val != -INF) ckmax(max_cur, max(y, val));
                }
                st.update(0, x, -INF, y, 1);
            }
            st.update(x, x + 1, min_cur, max_cur, 0);
        }
        rep(i, n) {
            ll lb = st.query(i, i + 1).mn;
            ll rb = st.query(i, i + 1).mx;
            if (0 <= lb && lb < n && qb[lb] >= qa[i]) {
                if (qa[i] == qb[lb]) {
                    took[qa[i]]++;
                }
                ans[abs(i - lb)]++;
            }
            if (0 <= rb && rb < n && lb != rb && qb[rb] >= qa[i]) {
                if (qa[i] == qb[rb]) {
                    took[qa[i]]++;
                }
                ans[abs(i - rb)]++;
            }
        }
        swap(a, b);
    }
    rep(i, n) if (took[i] == 2) {
        ans[abs(a[i] - b[i])]--;
    }
    rep(i, n) cout << ans[i] << ' ';
    cout << '\n';
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout << setprecision(12) << fixed;
    int t = 1;
    cin >> t;
    rep(i, t) {
        solve();
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

4
2
1 2
2 1
5
2 4 1 5 3
2 4 1 5 3
5
1 2 3 4 5
5 4 3 2 1
8
5 8 3 4 2 7 1 6
4 6 3 8 5 1 2 7

output:

2 0 
5 0 0 0 0 
2 2 2 2 0 
5 5 2 2 1 0 0 0 

result:

ok 20 numbers

Test #2:

score: -100
Wrong Answer
time: 204ms
memory: 3636kb

input:

66664
7
4 2 6 5 7 1 3
6 5 3 1 4 7 2
10
6 8 10 7 5 1 4 3 9 2
5 10 3 8 6 7 2 9 1 4
9
3 2 4 8 7 6 9 1 5
8 1 2 9 6 7 4 3 5
10
4 3 9 6 7 2 10 1 8 5
3 5 4 1 2 7 10 9 6 8
5
3 4 1 2 5
5 1 3 2 4
5
2 4 3 5 1
2 3 1 4 5
6
2 6 1 3 4 5
6 4 5 1 3 2
10
10 1 2 7 5 8 4 3 9 6
9 4 2 3 6 1 7 8 5 10
5
1 2 4 5 3
4 1 2 5 3...

output:

4 4 2 2 1 0 0 
5 6 3 2 2 1 0 0 0 0 
5 6 3 2 1 0 0 0 0 
4 4 4 3 2 1 0 0 0 0 
5 3 0 0 0 
2 2 2 2 0 
3 3 3 1 0 0 
5 7 4 2 1 0 0 0 0 0 
5 2 0 0 0 
6 4 0 0 0 0 
3 3 2 0 0 
5 4 2 1 0 0 0 
3 2 3 1 0 0 
4 6 3 0 0 0 0 
3 4 3 2 1 0 0 
3 2 2 2 2 2 2 1 0 
4 5 3 1 0 0 0 
3 4 3 2 3 3 1 0 0 0 
8 5 0 0 0 0 0 0 
7 8...

result:

wrong answer 69th numbers differ - expected: '3', found: '4'