結果
問題 | No.619 CardShuffle |
ユーザー |
|
提出日時 | 2017-12-19 11:44:36 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 335 ms / 3,000 ms |
コード長 | 3,718 bytes |
コンパイル時間 | 1,074 ms |
コンパイル使用メモリ | 89,608 KB |
実行使用メモリ | 10,880 KB |
最終ジャッジ日時 | 2024-12-22 21:49:01 |
合計ジャッジ時間 | 7,591 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 35 |
ソースコード
#include <iostream>#include <vector>#include <algorithm>#include <string>#include <set>using namespace std;const int mod = 1e9 + 7;struct Modint {int n;Modint(int n = 0) : n(n) {}};Modint operator+(Modint a, Modint b) { return Modint((a.n += b.n) >= mod ? a.n - mod : a.n); }Modint operator-(Modint a, Modint b) { return Modint((a.n -= b.n) < 0 ? a.n + mod : a.n); }Modint operator*(Modint a, Modint b) { return Modint(1LL * a.n * b.n % mod); }Modint &operator+=(Modint &a, Modint b) { return a = a + b; }Modint &operator-=(Modint &a, Modint b) { return a = a - b; }Modint &operator*=(Modint &a, Modint b) { return a = a * b; }const int N = 1 << 17;struct ST {vector<Modint> dat;ST() : dat(N * 2, 1) {}void update(int k, Modint v) {dat[k + N] = v;for (int i = k + N >> 1; i > 0; i >>= 1) {dat[i] = dat[i * 2] * dat[i * 2 + 1];}}Modint query(int l, int r) {l += N;r += N;Modint ret = 1;while (l < r) {if (l & 1) ret *= dat[l++];if (r & 1) ret *= dat[--r];l >>= 1;r >>= 1;}return ret;}};struct STadd {vector<Modint> dat;STadd() : dat(N * 2, 0) {}void update(int k, Modint v) {dat[k + N] = v;for (int i = k + N >> 1; i > 0; i >>= 1) {dat[i] = dat[i * 2] + dat[i * 2 + 1];}}Modint query(int l, int r) {l += N;r += N;Modint ret = 0;while (l < r) {if (l & 1) ret += dat[l++];if (r & 1) ret += dat[--r];l >>= 1;r >>= 1;}return ret;}};int main() {int n;cin >> n;vector<string> c(n + 2);c[0] = "+";c[n + 1] = "+";for (int i = 1; i <= n; i++) {cin >> c[i];}ST tree;for (int i = 1; i <= n; i++) {if (i % 2 == 1) {tree.update(i, c[i].front() - '0');}}int q;cin >> q;STadd tree2;set<int> st;for (int i = 0; i <= n + 1; i++) {if (c[i] == "+") {st.insert(i);}}for (auto it = st.begin(); next(it) != st.end(); it++) {int l = *it;int r = *next(it);tree2.update(l, tree.query(l, r));}auto change = [&](int k, string t) {if (c[k] == "+" && t == "*") {tree2.update(k, 0);st.erase(k);auto it = prev(st.lower_bound(k));int l = *it;int r = *next(it);tree2.update(l, tree.query(l, r));} else if (c[k] == "*" && t == "+") {st.insert(k);auto it = st.lower_bound(k);int l = *prev(it);int m = *it;int r = *next(it);tree2.update(l, tree.query(l, m));tree2.update(m, tree.query(m, r));}c[k] = t;};auto change_v = [&](int k, Modint v) {tree.update(k, v);auto it = prev(st.lower_bound(k));int l = *it;int r = *next(it);tree2.update(l, tree.query(l, r));};while (q--) {string type;int x, y;cin >> type >> x >> y;if (type == "!") {if (x % 2 == 1) {Modint a = tree.dat[x + N];Modint b = tree.dat[y + N];change_v(x, b);change_v(y, a);} else {string a = c[x];string b = c[y];change(x, b);change(y, a);}} else {Modint ret = 0;x--;y++;while (x != y) {auto it = st.lower_bound(x);if (x < *it) {int tmp = min(*it, y);ret += tree.query(x, tmp);x = tmp;continue;}auto it2 = prev(st.upper_bound(y));if (y > *it2) {ret += tree.query(*it2, y);y = *it2;continue;}ret += tree2.query(*it, *it2);break;}cout << ret.n << endl;}}}