結果
問題 | No.619 CardShuffle |
ユーザー | kimiyuki |
提出日時 | 2017-12-19 20:27:27 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 937 ms / 3,000 ms |
コード長 | 3,709 bytes |
コンパイル時間 | 2,245 ms |
コンパイル使用メモリ | 209,232 KB |
実行使用メモリ | 36,388 KB |
最終ジャッジ日時 | 2024-06-02 05:07:59 |
合計ジャッジ時間 | 18,043 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 2 ms
6,940 KB |
testcase_03 | AC | 2 ms
6,940 KB |
testcase_04 | AC | 2 ms
6,944 KB |
testcase_05 | AC | 2 ms
6,944 KB |
testcase_06 | AC | 2 ms
6,944 KB |
testcase_07 | AC | 2 ms
6,944 KB |
testcase_08 | AC | 2 ms
6,940 KB |
testcase_09 | AC | 2 ms
6,940 KB |
testcase_10 | AC | 2 ms
6,944 KB |
testcase_11 | AC | 2 ms
6,944 KB |
testcase_12 | AC | 2 ms
6,940 KB |
testcase_13 | AC | 2 ms
6,944 KB |
testcase_14 | AC | 2 ms
6,940 KB |
testcase_15 | AC | 2 ms
6,940 KB |
testcase_16 | AC | 820 ms
36,184 KB |
testcase_17 | AC | 808 ms
36,156 KB |
testcase_18 | AC | 789 ms
36,328 KB |
testcase_19 | AC | 799 ms
36,224 KB |
testcase_20 | AC | 806 ms
36,180 KB |
testcase_21 | AC | 932 ms
36,248 KB |
testcase_22 | AC | 924 ms
36,252 KB |
testcase_23 | AC | 933 ms
36,172 KB |
testcase_24 | AC | 937 ms
36,236 KB |
testcase_25 | AC | 926 ms
36,248 KB |
testcase_26 | AC | 675 ms
36,180 KB |
testcase_27 | AC | 667 ms
36,268 KB |
testcase_28 | AC | 681 ms
36,144 KB |
testcase_29 | AC | 668 ms
36,152 KB |
testcase_30 | AC | 690 ms
36,340 KB |
testcase_31 | AC | 2 ms
6,944 KB |
testcase_32 | AC | 803 ms
36,196 KB |
testcase_33 | AC | 813 ms
36,388 KB |
testcase_34 | AC | 678 ms
36,248 KB |
testcase_35 | AC | 119 ms
6,944 KB |
ソースコード
#include <bits/stdc++.h> #define REP(i, n) for (int i = 0; (i) < int(n); ++ (i)) #define REP_R(i, n) for (int i = int(n) - 1; (i) >= 0; -- (i)) using ll = long long; using namespace std; template <class Monoid> struct segment_tree { typedef typename Monoid::underlying_type underlying_type; int n; vector<underlying_type> a; Monoid mon; segment_tree() = default; segment_tree(int a_n, underlying_type initial_value = Monoid().unit(), Monoid const & a_mon = Monoid()) : mon(a_mon) { n = 1; while (n < a_n) n *= 2; a.resize(2 * n - 1, mon.unit()); fill(a.begin() + (n - 1), a.begin() + ((n - 1) + a_n), initial_value); // set initial values REP_R (i, n - 1) a[i] = mon.append(a[2 * i + 1], a[2 * i + 2]); // propagate initial values } void point_set(int i, underlying_type z) { // 0-based a[i + n - 1] = z; for (i = (i + n) / 2; i > 0; i /= 2) { // 1-based a[i - 1] = mon.append(a[2 * i - 1], a[2 * i]); } } underlying_type range_concat(int l, int r) { // 0-based, [l, r) underlying_type lacc = mon.unit(), racc = mon.unit(); for (l += n, r += n; l < r; l /= 2, r /= 2) { // 1-based loop, 2x faster than recursion if (l % 2 == 1) lacc = mon.append(lacc, a[(l ++) - 1]); if (r % 2 == 1) racc = mon.append(a[(-- r) - 1], racc); } return mon.append(lacc, racc); } }; constexpr int mod = 1e9 + 7; constexpr int N = 4; typedef array<ll, N> vec4; typedef array<array<ll, N>, N> mat44; mat44 operator * (mat44 const & a, mat44 const & b) { mat44 c = {}; REP (k, N) REP (i, N) REP (j, N) (c[i][j] += a[i][k] * b[k][j]) %= mod; return c; } vec4 operator * (mat44 const & a, vec4 const & b) { vec4 c = {}; REP (k, N) REP (i, N) (c[i] += a[i][k] * b[k]) %= mod; return c; } mat44 to_matrix(ll (& a)[N][N]) { mat44 b = {}; REP (i, N) REP (j, N) b[i][j] = a[i][j]; return b; } mat44 unit_matrix() { mat44 f = {}; REP (i, N) f[i][i] = 1; return f; } struct matmul_monoid { typedef mat44 underlying_type; underlying_type unit() const { return unit_matrix(); } underlying_type append(underlying_type const & a, underlying_type const & b) const { return b * a; } }; mat44 digit(int d) { ll f[N][N] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, d, 10, 0 }, { 0, 0, 0, 1 }, }; return to_matrix(f); } mat44 mult() { ll f[N][N] = { { 1, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, }; return to_matrix(f); } mat44 add(bool is_positive = true) { ll f[N][N] = { { 1, 0, 1, 0 }, { 0, 0, 0, is_positive ? 1 : -1 }, { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, }; return to_matrix(f); } int get_result(mat44 const & f) { vec4 x { { 0, 1, 0, 1 } }; vec4 y = f * x; return (y[0] + y[2]) % mod; } int main() { // prepare int n; scanf("%d", &n); vector<char> c(n); REP (i, n) scanf(" %c", &c[i]); segment_tree<matmul_monoid> segtree(n); auto update = [&](int i) { mat44 a = c[i] == '+' ? add() : c[i] == '*' ? mult() : digit(c[i] - '0'); segtree.point_set(i, a); }; REP (i, n) update(i); // serve int q; scanf("%d", &q); while (q --) { char t; int x, y; scanf(" %c%d%d", &t, &x, &y); -- x; -- y; if (t == '!') { swap(c[x], c[y]); update(x); update(y); } else if (t == '?') { int result = get_result(segtree.range_concat(x, y + 1)); printf("%d\n", result); } } return 0; }