結果
問題 | No.2611 Count 01 |
ユーザー | Mitarushi |
提出日時 | 2024-01-07 15:56:59 |
言語 | C++23 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 592 ms / 6,000 ms |
コード長 | 4,441 bytes |
コンパイル時間 | 1,309 ms |
コンパイル使用メモリ | 84,392 KB |
実行使用メモリ | 151,040 KB |
最終ジャッジ日時 | 2024-09-28 03:35:01 |
合計ジャッジ時間 | 15,203 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 555 ms
150,892 KB |
testcase_04 | AC | 562 ms
150,824 KB |
testcase_05 | AC | 560 ms
151,040 KB |
testcase_06 | AC | 584 ms
150,912 KB |
testcase_07 | AC | 587 ms
151,040 KB |
testcase_08 | AC | 590 ms
151,040 KB |
testcase_09 | AC | 586 ms
150,912 KB |
testcase_10 | AC | 579 ms
150,912 KB |
testcase_11 | AC | 561 ms
150,960 KB |
testcase_12 | AC | 558 ms
150,816 KB |
testcase_13 | AC | 590 ms
150,912 KB |
testcase_14 | AC | 546 ms
150,912 KB |
testcase_15 | AC | 550 ms
151,040 KB |
testcase_16 | AC | 540 ms
150,992 KB |
testcase_17 | AC | 583 ms
151,040 KB |
testcase_18 | AC | 591 ms
150,912 KB |
testcase_19 | AC | 587 ms
150,912 KB |
testcase_20 | AC | 556 ms
150,812 KB |
testcase_21 | AC | 552 ms
150,912 KB |
testcase_22 | AC | 592 ms
150,912 KB |
ソースコード
#pragma GCC target("avx2") #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #include <cstdio> #include <cstdint> #include <vector> #include <algorithm> #include <array> template <typename T, typename U> struct SegmentTree { int n; std::vector<T> data; T e; SegmentTree(int n, T e) : e(e) { int n2 = 1; while (n2 < n) { n2 *= 2; } this->n = n2; this->data = std::vector<T>(n2 * 2, e); } void build() { for (int i = this->n - 1; i >= 1; i--) { this->data[i] = this->data[i * 2] + this->data[i * 2 + 1]; } } void update(int i, T x) { int k = i + this->n; this->data[k] = x; while (k > 1) { k /= 2; this->data[k] = this->data[k * 2] + this->data[k * 2 + 1]; } } auto query(int l, int r, U ls, U rs) { l += this->n; r += this->n; while (l < r) { if (l & 1) { ls = ls + this->data[l]; l++; } if (r & 1) { r--; rs = this->data[r] + rs; } l /= 2; r /= 2; } return ls + rs; } }; using int64 = std::int64_t; constexpr int64 MOD = 998244353; struct Vec { std::array<int64, 6> data; Vec() { std::fill_n(this->data.begin(), 6, 0); } Vec(const int (&a)[6]) { std::copy_n(a, 6, this->data.begin()); } }; struct Matrix { std::array<std::array<int64, 6>, 6> data; Matrix() { std::fill_n(this->data.begin(), 6, std::array<int64, 6>()); for (int i = 0; i < 6; i++) { std::fill_n(this->data[i].begin(), i + 1, 0); } } Matrix(const int (&a)[6][6]) { for (int i = 0; i < 6; i++) { std::copy_n(a[i], i + 1, this->data[i].begin()); } } }; Matrix operator+(const Matrix &a, const Matrix &b) { Matrix result; for (int i = 0; i < 6; i++) { for (int j = 0; j <= i; j++) { for (int k = j; k <= i; k++) { result.data[i][j] += a.data[i][k] * b.data[k][j]; } result.data[i][j] %= MOD; } } return result; } Vec operator+(const Vec &a, const Matrix &b) { Vec result; for (int i = 0; i < 6; i++) { for (int j = 0; j <= i; j++) { result.data[j] += a.data[i] * b.data[i][j]; } } for (int i = 0; i < 6; i++) { result.data[i] %= MOD; } return result; } Vec operator+(const Matrix &a, const Vec &b) { Vec result; for (int i = 0; i < 6; i++) { for (int j = 0; j <= i; j++) { result.data[i] += a.data[i][j] * b.data[j]; } } for (int i = 0; i < 6; i++) { result.data[i] %= MOD; } return result; } int64 operator+(const Vec &a, const Vec &b) { int64 result = 0; for (int i = 0; i < 6; i++) { result += a.data[i] * b.data[i]; } return result % MOD; } const std::array<Matrix, 2> node = {{ Matrix({ {1, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 0, 0}, {1, 1, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0}, {0, 0, 0, 1, 1, 0}, {0, 0, 0, 1, 1, 1}, }), Matrix({ {1, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 0}, {1, 1, 0, 1, 0, 0}, {0, 0, 1, 0, 1, 0}, {0, 0, 1, 0, 1, 1}, }) }}; const Matrix identity = Matrix({ {1, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1}, }); int main() { int n, q; scanf("%d%d", &n, &q); std::vector<int> s(n); for (int i = 0; i < n; i++) { char c; scanf(" %c", &c); s[i] = c - '0'; } SegmentTree<Matrix, Vec> st(n, identity); for (int i = 0; i < n; i++) { st.data[i + st.n] = node[s[i]]; } st.build(); for (int i = 0; i < q; i++) { int t; scanf("%d", &t); if (t == 1) { int j; scanf("%d", &j); j--; s[j] = 1 - s[j]; st.update(j, node[s[j]]); } else { int l, r; scanf("%d%d", &l, &r); l--; int64 ans = st.query(l, r, Vec({0, 0, 0, 0, 0, 1}), Vec({1, 0, 0, 0, 0, 0})); printf("%lld\n", ans); } } }