結果
問題 | No.2762 Counting and Deleting |
ユーザー |
![]() |
提出日時 | 2025-01-10 23:21:16 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 301 ms / 4,000 ms |
コード長 | 7,576 bytes |
コンパイル時間 | 9,340 ms |
コンパイル使用メモリ | 332,460 KB |
実行使用メモリ | 10,716 KB |
最終ジャッジ日時 | 2025-01-10 23:21:30 |
合計ジャッジ時間 | 10,030 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 15 |
ソースコード
#include <bits/stdc++.h> #if __has_include(<atcoder/all>) #include <atcoder/all> std::istream &operator>>(std::istream &is, atcoder::modint &v) { long long value; is >> value; v = value; return is; } std::ostream &operator<<(std::ostream &os, const atcoder::modint &v) { os << v.val(); return os; } std::ostream &operator<<(std::ostream &os, const atcoder::modint998244353 &v) { os << v.val(); return os; } std::istream &operator>>(std::istream &is, atcoder::modint998244353 &v) { long long x; is >> x; v = x; return is; } std::ostream &operator<<(std::ostream &os, const atcoder::modint1000000007 &v) { os << v.val(); return os; } std::istream &operator>>(std::istream &is, atcoder::modint1000000007 &v) { long long x; is >> x; v = x; return is; } #endif using namespace std; using ll = long long; using pll = pair<ll, ll>; #define newl '\n'; #define rep(i, s, t) for (ll i = s; i < (ll)(t); i++) #define rrep(i, s, t) for (ll i = (ll)(t) - 1; i >= (ll)(s); i--) #define all(x) begin(x), end(x) #define eb emplace_back #define pb push_back #define TT template <typename T> TT using vec = vector<T>; TT using vvec = vec<vec<T>>; TT using vvvec = vec<vvec<T>>; TT using minheap = priority_queue<T, vector<T>, greater<T>>; TT using maxheap = priority_queue<T>; TT bool chmin(T &x, T y) { return x > y ? (x = y, true) : false; } TT bool chmax(T &x, T y) { return x < y ? (x = y, true) : false; } TT bool rng(T l, T x, T r) { return l <= x && x < r; } TT T flr(T a, T b) { if (b < 0) a = -a, b = -b; return a >= 0 ? a / b : (a + 1) / b - 1; } TT T cil(T a, T b) { if (b < 0) a = -a, b = -b; return a > 0 ? (a - 1) / b + 1 : a / b; } TT T sqr(T x) { return x * x; } struct io_setup { io_setup() { ios::sync_with_stdio(false); std::cin.tie(nullptr); cout << fixed << setprecision(15); } } io_setup; template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &p) { os << p.first << " " << p.second; return os; } TT ostream &operator<<(ostream &os, const vec<T> &v) { for (size_t i = 0; i < v.size(); i++) { os << v[i] << (i + 1 != v.size() ? " " : ""); } return os; } template <typename T, ll n> ostream &operator<<(ostream &os, const array<T, n> &v) { for (size_t i = 0; i < n; i++) { os << v[i] << (i + 1 != n ? " " : ""); } return os; } template <typename T> ostream &operator<<(ostream &os, const vvec<T> &v) { for (size_t i = 0; i < v.size(); i++) { os << v[i] << (i + 1 != v.size() ? "\n" : ""); } return os; } TT istream &operator>>(istream &is, vec<T> &v) { for (size_t i = 0; i < v.size(); i++) { is >> v[i]; } return is; } #if __has_include(<debug/debug.hpp>) #include <debug/debug.hpp> #else #define dbg(...) true #define DBG(...) true #define OUT(...) true #endif template <typename T, bool merge_adju> struct rangeset : public std::map<T, T> { rangeset() {} auto get(T p) const { auto it = (*this).upper_bound(p); if (it == (*this).begin() || (--it)->second <= p) return (*this).end(); return it; } //[l, r) void insert(T l, T r) { if (l == r) return; assert(l <= r); auto itl = (*this).upper_bound(l), itr = (*this).lower_bound(r + merge_adju); if (itl != (*this).begin() && (--itl)->second + merge_adju <= l) { ++itl; } if (itl != itr) { if (itl->first < l) l = itl->first; if (prev(itr)->second > r) r = prev(itr)->second; map<T, T>::erase(itl, itr); } (*this)[l] = r; } //[l, r) void erase(T l, T r) { if (l == r) return; assert(l <= r); auto itl = (*this).upper_bound(l), itr = (*this).lower_bound(r); if (itl != (*this).begin() && (--itl)->second <= l) { ++itl; } if (itl == itr) return; T tl = l, tr = r; if (itl->first < l) tl = itl->first; if (prev(itr)->second > r) tr = prev(itr)->second; map<T, T>::erase(itl, itr); if (tl < l) (*this)[tl] = l; if (tr > r) (*this)[r] = tr; } bool contains(T p) const { return get(p) != (*this).end(); } bool same(T a, T b) const { if (a > b) swap(a, b); auto it = get(a); if (it == (*this).end()) return false; return b < it->second; } T mex(T x = 0) const { auto it = get(x); if (it == (*this).end()) return x; else return it->second; } template <typename TYPE, bool ME> friend ostream &operator<<(ostream &os, rangeset<TYPE, ME> const &rhs) { for (auto [l, r] : rhs) os << "[" << l << ", " << r << ")"; return os; } }; template <typename T, int h, int w> struct Matrix { array<array<T, w>, h> d; Matrix(T val = 0) { rep(i, 0, h) rep(j, 0, w) d[i][j] = val; } Matrix(array<array<T, w>, h> const &dat) : d(dat) {} Matrix(vector<vector<T>> const & dat) { assert(dat.size() == h && dat[0].size() == w); rep(i, 0, h) rep(j, 0, w) d[i][j] = dat[i][j]; } template <int n> static Matrix<T, n, n> unit() { Matrix<T, n, n> uni; rep(i, 0, n) { uni[i][i] = 1; } return uni; } const array<T, w> &operator[](int i) const { return d[i]; } array<T, w> &operator[](int i) { return d[i]; } template <int w2> Matrix &operator*=(const Matrix<T, w, w2> &a) { return *this = (*this) * a; } template <int w2> Matrix<T, h, w2> operator*(const Matrix<T, w, w2> &a) const { Matrix<T, h, w2> r(0); rep(i, 0, h) { rep(k, 0, w) { rep(j, 0, w2) { r[i][j] += d[i][k] * a[k][j]; } } } return r; } Matrix pow(ll t) const { assert(h == w); Matrix res = Matrix::unit<h>(); Matrix x = (*this); while (t > 0) { if (t & 1) res = res * x; x = x * x; t >>= 1; } return res; } friend ostream &operator<<(ostream &os, Matrix a) { for (int i = 0; i < a.h; i++) { for (int j = 0; j < a.w; j++) { os << a[i][j] << (j != a.w - 1 ? " " : ""); } os << (i != a.h - 1 ? "\n" : ""); } return os; } }; using mint = atcoder::modint998244353; using matrix = Matrix<mint, 3, 3>; matrix op(matrix l, matrix r) { return r * l; } matrix e() { return matrix::unit<3>(); } int main() { ll n, q; cin >> n >> q; string S; cin >> S; matrix one = vvec<mint>{{1, 0, 1}, {0, 1, 1}, {0, 0, 1}}; matrix zero = vvec<mint>{{1, 1, 0}, {0, 1, 0}, {0, 1, 1}}; atcoder::segtree<matrix, op, e> seg(n); rep(i, 0, n) { if (S[i] == '0') seg.set(i, zero); else seg.set(i, one); } Matrix<mint, 3, 1> first = vvec<mint>{{1}, {0}, {1}}; set<int> remain; rep(i, 0, n) remain.insert(i); while (q--) { ll t, l, r; cin >> t >> l >> r; l--; if (t == 1) { auto it = remain.lower_bound(l); while (it != remain.end() && (*it) < r) { seg.set(*(it), matrix::unit<3>()); remain.erase(it++); } } else { auto ret = seg.prod(l, r); auto ret2 = ret * first; // DBG(ret); // dbg(ret2); cout << ret2[0][0] - 1 << newl; } } }