Да Да делится на дискуссии, и идеи все еще очень умны.
код:
#include <bits / stdc ++. h> #define ll long long #define lson now << 1 #define rson now << 1 | 1 #define N 100008 #define mod 998244353 #define setIO (s) freopen (s) .in "," r ", stdin) используя пространство имен std; int n, m, cur; ll f [N << 3], g [N << 3], SUM [N << 3], qp [N], mf [N << 3], мг [N << 3]; void markf (int now, int v) { f [сейчас] = (ll) f [сейчас] * qp [v]% mod; СУММА [теперь] = (LL) СУММА [теперь] * QP [V]% по модулю; М.Ф. [теперь] + = v; } void markg (int now, int v) { g [now] = (ll) g [now] * qp [v]% mod; мг [теперь] + = v; if (mf [сейчас]) void update (int l, int r, int now, int L, int R) { markf (lson, mf [сейчас]); markf (rson, М.Ф. [теперь]); М.Ф. [теперь] = 0; } if (mg [сейчас]) { markg (lson, мг [сейчас]); markg (rson, мг [теперь]); мг [теперь] = 0; } } void pushup (int now) { SUM [сейчас] = (ll) (SUM [lson] + SUM [rson] + f [сейчас])% mod; } void build (int l, int r, int now) { f [сейчас] = 0, g [сейчас] = 1; if (l == r) возврат; int mid = (l + r) >> 1; сборки (л, середина, lson), сборка (середина + 1, г, rson); } { pushdown (сейчас); if (l> = L && r <= R) магазинный (р); { // 1 点 点 f [сейчас] = (ll) (f [сейчас] + qp [cur-1])% mod; markf (lson, 1), markf (rson, 1); отжимания ( в настоящее время); возвращение; } int mid = (l + r) >> 1; if (L <= mid && R> mid) { update (l, mid, lson, L, R); обновление (середина + 1, г, rson, L, R); } else if (L <= mid) { update (l, mid, lson, L, R); int p = rson; markf (р << 1,1), markf (р << 1 | 1,1); markg (р << 1,1), markg (р << 1 | 1,1); г [р] = (LL) (г [р] + д [р])% по модулю; отжимания (р); } else { update (mid + 1, r, rson, L, R); int p = lson; магазинный (р); markf (р << 1,1), markf (р << 1 | 1,1); markg (р << 1,1), markg (р << 1 | 1,1); е [р] = (LL) (е [р] + QP [текущ-1] -g [р] + моды)% по модулю; г [р] = (LL) (г [р] + д [р])% по модулю; отжимания (р); } // 2 点 点 // g [сейчас] = (ll) (g [сейчас] + qp [cur-1])% mod; отжимания ( в настоящее время); } int main () { // setIO ("вход"); QP [0] = 1; для (int i = 1; i <N; ++ i) qp [i] = (ll) qp [i-1] * 2% mod; зсапЕ ( "% d% d", & п, & м); сборки (1, п, 1); for (int i = 1; i <= m; ++ i) { int op, l, r; зсапЕ ( "% d", & оп); if (op == 1) { scanf ("% d% d", & l, & r), ++ cur, update (1, n, 1, l, r); } else { printf ("% lld \ n", SUM [1]); } } return 0; }