結果
問題 | No.619 CardShuffle |
ユーザー |
|
提出日時 | 2017-12-19 20:27:27 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,113 ms / 3,000 ms |
コード長 | 3,709 bytes |
コンパイル時間 | 2,507 ms |
コンパイル使用メモリ | 203,452 KB |
最終ジャッジ日時 | 2025-01-05 05:54:28 |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 35 |
コンパイルメッセージ
main.cpp: In function ‘int main()’: main.cpp:103:17: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 103 | int n; scanf("%d", &n); | ~~~~~^~~~~~~~~~ main.cpp:104:40: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 104 | vector<char> c(n); REP (i, n) scanf(" %c", &c[i]); | ~~~~~^~~~~~~~~~~~~~ main.cpp:115:17: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 115 | int q; scanf("%d", &q); | ~~~~~^~~~~~~~~~ main.cpp:117:32: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 117 | char t; int x, y; scanf(" %c%d%d", &t, &x, &y); -- x; -- y; | ~~~~~^~~~~~~~~~~~~~~~~~~~~~~
ソースコード
#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 valuesREP_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-baseda[i + n - 1] = z;for (i = (i + n) / 2; i > 0; i /= 2) { // 1-baseda[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 recursionif (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() {// prepareint 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);// serveint 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;}