結果
問題 | No.619 CardShuffle |
ユーザー |
|
提出日時 | 2017-12-13 05:12:13 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 1,521 ms / 3,000 ms |
コード長 | 3,464 bytes |
コンパイル時間 | 3,487 ms |
コンパイル使用メモリ | 100,988 KB |
実行使用メモリ | 99,464 KB |
最終ジャッジ日時 | 2024-12-22 21:20:11 |
合計ジャッジ時間 | 26,270 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 35 |
ソースコード
// ConsoleApplication19.cpp : Defines the entry point for the console application.//#include <unordered_set>#include <string>#include <cmath>#include <cstdio>#include <vector>#include <algorithm>#include <iostream>#include <queue>#include <tuple>#include <functional>#include <set>using namespace std;struct V {deque<long long> dq;string left_op = "!";string right_op = "!";};long long MOD = 1000000000 + 7;V merge(V u, V v) {V ret;for (long long n : u.dq) {ret.dq.push_back(n);}bool f = false;if (u.right_op == ("*") && v.left_op == ("*")) {ret.dq.pop_back();ret.dq.push_back(u.dq.back() * v.dq.front() % MOD);f = true;}for (long long n : v.dq) {if (!f)ret.dq.push_back(n);elsef = false;}if (ret.dq.size() > 3) {long long tmp1 = ret.dq.front();ret.dq.pop_front();while (ret.dq.size() > 3) {long long tmp2 = 0;tmp2 += ret.dq.front();ret.dq.pop_front();tmp2 += ret.dq.front();ret.dq.pop_front();if (tmp2 >= MOD)tmp2 -= MOD;ret.dq.push_front(tmp2);}ret.dq.push_front(tmp1);}ret.left_op = u.left_op;ret.right_op = v.right_op;return ret;}struct SegTree {int n;vector<V> val;SegTree(int n_) {n = 1;while (n < n_) {n *= 2;}val.resize(2 * n - 1);}void swapOp(int i, int j) {i += n - 1;j += n - 1;string opI = val[i].right_op;string opJ = val[j].right_op;if (opI==opJ)return;val[i].right_op = opJ;val[i + 1].left_op = opJ;val[j].right_op = opI;val[j + 1].left_op = opI;int a[] = { i, i + 1, j, j + 1 };while (a[0] > 0) {for (int k = 0; k < 4; ++k) {a[k] = (a[k] - 1) / 2;val[a[k]] = merge(val[2 * a[k] + 1], val[2 * a[k] + 2]);}}}void swapVal(int i, int j) {long long x = val[i + n - 1].dq.back();long long y = val[j + n - 1].dq.back();if (x == y)return;setVal(i, y);setVal(j, x);}void setVal(int k, long long v) {k += n - 1;val[k].dq.clear();val[k].dq.push_back(v);while (k > 0) {k = (k - 1) / 2;val[k] = merge(val[2 * k + 1], val[2 * k + 2]);}}long long query(int a, int b) {long long ret = 0;V pnd = query(a, b, 0, n, 0);for (long long v : pnd.dq) {ret = ret + v;if (ret >= MOD)ret -= MOD;}return ret;}V query(int a, int b, int l, int r, int k) {if (b <= l || r <= a) {return V();}else if (a <= l && r <= b) {return val[k];}else {V vl = query(a, b, l, (l + r) / 2, 2 * k + 1);V vr = query(a, b, (l + r) / 2, r, 2 * k + 2);return merge(vl, vr);}}};void run() {int n;cin >> n;n = (n + 1) / 2;SegTree seg(n);for (int i = 0; i < n; ++i) {long long v;cin >> v;int j = i + seg.n - 1;string leftop = "!", rightop = "!";if (i != n - 1)cin >> rightop;if (i != 0)leftop = seg.val[j - 1].right_op;seg.val[j].dq.push_back(v);seg.val[j].left_op = leftop;seg.val[j].right_op = rightop;}for (int i = seg.n - 2; i >= 0; --i) {seg.val[i] = merge(seg.val[2 * i + 1], seg.val[2 * i + 2]);}int Q;cin >> Q;while (Q-- > 0) {string T;int x, y;cin >> T >> x >> y;if (T == "?") {cout << (seg.query((x - 1) / 2, (y - 1) / 2 + 1)) << endl;}else {if (x % 2 == 1) {x = (x - 1) / 2;y = (y - 1) / 2;seg.swapVal(x, y);}else {x = x / 2 - 1;y = y / 2 - 1;seg.swapOp(x, y);}}}}int main() {run();return 0;}