Editorial for Dãy số Teto
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
#include <bits/stdc++.h> using namespace std; using int64 = long long; const int MOD = 998244353; const int H = 30; const int MAX_N = 100000; const int MAX_Q = 100000; const int MAX_OPS = MAX_N + MAX_Q + 5; // Around 48M nodes. // sizeof(Node) = 20 bytes. // Total memory ~= 960 MB decimal ~= 916 MiB. const int MAX_NODE = 4 * H * MAX_OPS + 5; struct Node { int left; int right; int cover; int cnt; int ans; }; Node d[MAX_NODE]; int pow2mod[H + 1]; int fullAns[H + 1]; int nodeCnt = 0; inline int newNode() { ++nodeCnt; return nodeCnt; } inline int addMod(int a, int b) { int s = a + b; if (s >= MOD) s -= MOD; return s; } void precompute() { pow2mod[0] = 1; for (int i = 1; i <= H; i++) { pow2mod[i] = 2LL * pow2mod[i - 1] % MOD; } fullAns[0] = 1; for (int h = 1; h <= H; h++) { long long factor = 2LL + pow2mod[h - 1]; fullAns[h] = 1LL * fullAns[h - 1] * (factor % MOD) % MOD; } } inline void pull(int id, int h) { if (d[id].cover > 0) { d[id].cnt = pow2mod[h]; d[id].ans = fullAns[h]; return; } if (h == 0) { d[id].cnt = 0; d[id].ans = 0; return; } int left = d[id].left; int right = d[id].right; int cntL = left ? d[left].cnt : 0; int cntR = right ? d[right].cnt : 0; int ansL = left ? d[left].ans : 0; int ansR = right ? d[right].ans : 0; int cnt = cntL + cntR; if (cnt >= MOD) cnt -= MOD; d[id].cnt = cnt; int res = addMod(ansL, ansR); res = (res + 1LL * ansL * cntR) % MOD; d[id].ans = res; } void update( int id, int64 L, int64 R, int64 qL, int64 qR, int delta, int h ) { if (qR <= L || R <= qL) { return; } if (qL <= L && R <= qR) { d[id].cover += delta; pull(id, h); return; } int64 M = (L + R) >> 1; if (qL < M) { if (!d[id].left) { d[id].left = newNode(); } update(d[id].left, L, M, qL, qR, delta, h - 1); } if (M < qR) { if (!d[id].right) { d[id].right = newNode(); } update(d[id].right, M, R, qL, qR, delta, h - 1); } pull(id, h); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); precompute(); int n, q; cin >> n >> q; const int64 DOMAIN_L = 0; const int64 DOMAIN_R = 1LL << H; // [0, 2^60) int root = newNode(); for (int i = 0; i < n; i++) { int64 l, r; cin >> l >> r; update(root, DOMAIN_L, DOMAIN_R, l, r + 1, +1, H); } cout << d[root].ans << '\n'; for (int i = 0; i < q; i++) { int t; int64 u, v; cin >> t >> u >> v; if (t == 1) { update(root, DOMAIN_L, DOMAIN_R, u, v + 1, +1, H); } else { update(root, DOMAIN_L, DOMAIN_R, u, v + 1, -1, H); } cout << d[root].ans << '\n'; } return 0; }
Comments