QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#45960#4391. Slayers ComemiaomiaoziAC ✓107ms16964kbC++177.3kb2022-08-24 18:47:062022-08-24 18:51:01

Judging History

This is the latest submission verdict.

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-08-24 18:51:01]
  • Judged
  • Verdict: AC
  • Time: 107ms
  • Memory: 16964kb
  • [2022-08-24 18:47:06]
  • Submitted

answer

#include <bits/stdc++.h>
using namespace std;
// https://space.bilibili.com/672346917

#ifndef LOCAL
#define LOG(...) 42
#endif

#define fi first
#define se second
#define pb push_back
#define endl '\n'
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

typedef long long LL;
typedef pair <int, int> PII;

constexpr int inf = 0x3f3f3f3f;
constexpr double EPS = 1e-8;
const double PI = acos(-1);

int multi_cases = 1;

struct DSU {
    int components, n;
    vector <int> f, siz;
    DSU (int _n = 1) : components(_n), n(_n + 5), f(n), siz(n, 1) {
        iota(f.begin(), f.end(), 0);
    }
    int find(int x) {
        while (x != f[x]) x = f[x] = f[f[x]];
        return x;
    }
    int operator [](int x) { return find(x); }
    int same(int a, int b) { return find(a) == find(b); }
    bool merge(int a, int b) {
        a = find(a), b = find(b);
        if (a == b) return false;
        components--;
        siz[b] += siz[a];
        f[a] = b;
        return true;
    }
    int size(int x) { return siz[find(x)]; }
    int count() { return components; }
};

// constexpr int P = 1000000007;
constexpr int P = 998244353;

// assume -p <= x < 2P
int norm(int x) {
    if (x < 0) { x += P; }
    if (x >= P) { x -= P; }
    return x;
}
template<class T>
T power(T a, int b) {
    T res = 1;
    for (; b; b >>= 1, a *= a)  if (b & 1) res *= a;
    return res;
}
struct Z {
    int x;
    Z(int x = 0) : x(norm(x)) {}
    int val() const { return x; }
    Z operator-() const { return Z(norm(P - x)); }
    Z inv() const { assert(x != 0); return power(*this, P - 2); }
    Z &operator*=(const Z &rhs) { x = (long long)(x) * rhs.x % P; return *this; }
    Z &operator+=(const Z &rhs) { x = norm(x + rhs.x); return *this; }
    Z &operator-=(const Z &rhs) { x = norm(x - rhs.x); return *this; }
    Z &operator/=(const Z &rhs) { return *this *= rhs.inv(); }
    friend Z operator*(const Z &lhs, const Z &rhs) { Z res = lhs; res *= rhs; return res; }
    friend Z operator+(const Z &lhs, const Z &rhs) { Z res = lhs; res += rhs; return res; }
    friend Z operator-(const Z &lhs, const Z &rhs) { Z res = lhs; res -= rhs; return res; }
    friend Z operator/(const Z &lhs, const Z &rhs) { Z res = lhs; res /= rhs; return res; }
    friend bool operator==(const Z &lhs, const Z &rhs) { return lhs.val() == rhs.val(); }
    friend istream &operator >> (istream &input, Z &o) {  input >> o.x; return input; }
    friend ostream &operator << (ostream &output, const Z &o) { output << o.val(); return output; }
};

template <typename T = long long>
struct SegTree {
    struct node {
        int l, r;
        Z sum = 0, mul = 1;
    };
    int n;
    vector <node> tr;
    vector <T> a;

    SegTree(int _n = 1): n(_n), tr((_n + 5) << 2), a(_n + 5, T(0)) {
        build(1, 1, n);
    }
    SegTree(int _n, const vector <T> &_a) : n(_n), tr((_n + 5) << 2), a(_a) {
        build(1, 1, n);
    }

    void init(int u, int r) {
        assert(1 <= r && r <= n);
        tr[u].sum = 0;
        tr[u].mul = 1;
    }
    void pushup(node &u, node &l, node &r) {
        u.sum = l.sum + r.sum;
    }
    void pushdown(node &u, node &l, node &r) {
        if (u.mul.val() > 1) {
            auto &v = u.mul;
            l.mul *= v, r.mul *= v;
            l.sum *= v, r.sum *= v;
            u.mul.x = 1;
        }
    }
    void add(int u, int x, Z c) {
        if (tr[u].l == tr[u].r && tr[u].r == x) {
            tr[u].sum += c;
            return;
        }
        pushdown(u);
        int mid = tr[u].l + tr[u].r >> 1;
        if (x <= mid) add(u << 1, x, c);
        else add(u << 1 | 1, x, c);
        pushup(u);
    }
    void modify(int u, int l, int r, Z c) {
        if(tr[u].l >= l && tr[u].r <= r) {
            tr[u].mul *= c;
            tr[u].sum *= c;
            return;
        }
        pushdown(u);
        int mid = tr[u].l + tr[u].r >> 1;
        if(l <= mid) modify(u << 1, l, r, c);
        if(r > mid) modify(u << 1 | 1, l, r, c);
        pushup(u);
    }
    LL len(int &u) {
        return 1LL * tr[u].r - tr[u].l + 1;
    }
    LL len(node &u) {
        return 1LL * u.r - u.l + 1; 
    }
    void pushup(int u) {
        pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
    }
    void pushdown(int u) {
        pushdown(tr[u], tr[u << 1], tr[u << 1 | 1]);
    }
    void build(int u, int l, int r) {
        tr[u].l = l, tr[u].r = r;
        if(l == r) {
            init(u, r);
            return;
        }
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }
    node query(int u, int l, int r) {
        if(tr[u].l >= l && tr[u].r <= r) {
            return tr[u];
        }
        pushdown(u);
        int mid = tr[u].l + tr[u].r >> 1;
        if(r <= mid) return query(u << 1, l, r);
        else if (l > mid) return query(u << 1 | 1, l, r);
        else {
            node res, left, right;
            left = query(u << 1, l, r);
            right = query(u << 1 | 1, l, r);
            pushup(res, left, right);
            return res;
        }
    }
};

void A_SOUL_AvA () {
    int n, m;
    cin >> n >> m;
    vector <LL> a(n + 5), b(n + 5);
    b[0] = b[n + 1] = 1e18;
    for (int i = 1; i <= n; i++) {
        cin >> a[i] >> b[i];
    }

    vector <array<LL, 4>> skills(m);
    // x_i, L, R, idx
    for (int i = 0; i < m; i++) {
        auto &[a, b, c, d] = skills[i];
        cin >> a >> b >> c;
        d = i;
    }

    sort(all(skills), [&](auto &u, auto &v) {
        return u[1] > v[1];
    });

    DSU left(n);
    vector <int> to_left(m), to_right(m);
    for (auto &[x, L, R, idx] : skills) {
        int i = left[x];
        while (i && L <= a[i] - b[i - 1]) {
            left.merge(i, i - 1);
            i--;
        }
        to_left[idx] = i;
    }
    DSU right(n + 1);
    sort(all(skills), [&](auto &u, auto &v) {
        return u[2] > v[2];
    });

    for (auto &[x, L, R, idx] : skills) {
        int i = right[x];
        while (i < n && R <= a[i] - b[i + 1]) {
            right.merge(i, i + 1);
            i++;
        }
        to_right[idx] = i;
    }

    vector <PII> interval(m);
    for (int i = 0; i < m; i++) {
        assert(to_left[i] <= to_right[i]);
        interval[i] = {to_left[i], to_right[i]};
    }

    sort(all(interval), [&](auto &u, auto &v) {
        if (u.se != v.se) {
            return u.se < v.se;
        }
        return u.fi < v.fi;
    });

    SegTree <Z> st(n + 1);
    st.add(1, 1, 1);
    for (auto &[l, r] : interval) {
        Z s = st.query(1, l, r + 1).sum;
        st.add(1, r + 1, s);
        if (l - 1 >= 1) st.modify(1, 1, l - 1, Z(2));
    }

    cout << st.query(1, n + 1, n + 1).sum << endl;
/*
    vector <Z> f(n + 1);
    f[0] = 1;
    for (auto &[l, r] : interval) {
        Z s = 0;
        for (int i = l - 1; i <= r; i++) {
            s += f[i];
        }
        f[r] += s;
        for (int i = 0; i < l - 1; i++) {
            // f[i] += f[i];
            f[i] *= 2;
        }
    }
    cout << f[n] << endl;
*/  

}

int main () {
    cin.tie(nullptr)->sync_with_stdio(false);
    cout << fixed << setprecision(12);

    int T = 1;
    for (multi_cases && cin >> T; T; T--) {
        A_SOUL_AvA ();
    }

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 107ms
memory: 16964kb

input:

100
94361 94314
33869598 5185471
618720133 505036749
409602893 40833389
73363932 853969687
132417645 381351032
465347847 676007624
210787499 3355224
991034578 503557482
118882583 12886598
821718576 953581962
979222818 458179522
17341621 962353208
11732262 180321038
947467293 869555337
27442910 91111...

output:

790989612
671747997
0
437770386
293758108
417733173
876589319
754905430
511705067
4194304
908866994
0
362293000
268315788
810816358
587847598
378811885
673322235
478150607
897151370
331537435
714057465
262017639
527438203
922745986
484494985
318652554
331818541
767356752
601981094
34519446
0
5190730...

result:

ok 100 lines