QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#45960 | #4391. Slayers Come | miaomiaozi | AC ✓ | 107ms | 16964kb | C++17 | 7.3kb | 2022-08-24 18:47:06 | 2022-08-24 18:51:01 |
Judging History
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