Submission #1163372

#TimeUsernameProblemLanguageResultExecution timeMemory
1163372fryingducCrossing (JOI21_crossing)C++20
100 / 100
409 ms17964 KiB
#include "bits/stdc++.h" using namespace std; #ifdef duc_debug #include "bits/debug.h" #else #define debug(...) #endif const int maxn = 2e5 + 5; const int base = 31; const int mod = 1e9 + 9; int p[maxn]; int n, q; string sa, sb, sc, t; int hc[4][maxn]; string crossing(string x, string y) { string t; for (int i = 0; i < n; ++i) { if (x[i] == y[i]) t += x[i]; else { if (x[i] != 'J' and y[i] != 'J') t += 'J'; else if (x[i] != 'O' and y[i] != 'O') t += 'O'; else t += 'I'; } } return t; } int convert(char c) { if (c == 'J') return 1; if (c == 'O') return 2; if (c == 'I') return 3; return -1; } int build_hash(string s) { reverse(s.begin(), s.end()); int h = 0; for (int i = 0; i < (int)s.size(); ++i) { (h = 1ll * h * base % mod + convert(s[i])) %= mod; } return h; } struct node { int val, len; node() { val = len = 0; } node (int val, int len) : val(val), len(len) {} node operator+(const node &o) const { node res = o; res.val = 1ll * res.val * p[len] % mod; res.val = res.val + val; if (res.val >= mod) res.val -= mod; res.len += len; return res; } } tree[maxn << 2]; int lazy[maxn << 2]; void build(int ind = 1, int l = 1, int r = n) { if (l == r) { tree[ind] = node(convert(t[l - 1]), 1); return; } int mid = (l + r) >> 1; build(ind << 1, l, mid); build(ind << 1 | 1, mid + 1, r); tree[ind] = tree[ind << 1] + tree[ind << 1 | 1]; } void down(int ind, int l, int r) { tree[ind].val = hc[lazy[ind]][r - l + 1]; if (l != r) { lazy[ind << 1] = lazy[ind << 1 | 1] = lazy[ind]; } lazy[ind] = 0; } void update(int x, int y, int val, int ind = 1, int l = 1, int r = n) { if (lazy[ind]) down(ind, l, r); if (l > y || r < x) return; if (x <= l and r <= y) { lazy[ind] = val; down(ind, l, r); return; } int mid = (l + r) >> 1; update(x, y, val, ind << 1, l, mid); update(x, y, val, ind << 1 | 1, mid + 1, r); tree[ind] = tree[ind << 1] + tree[ind << 1 | 1]; } int get() { if (lazy[1]) down(1, 1, n); return tree[1].val; } void solve() { cin >> n >> sa >> sb >> sc; set<string> s; s.insert(sa); s.insert(sb); s.insert(sc); set<string> ns; while (true) { for (auto i:s) { for (auto j:s) { if (i == j) continue; ns.insert(crossing(i, j)); } } bool flag = 0; for (auto i:ns) { if (!s.count(i)) { flag = 1; s.insert(i); } } if (!flag) break; ns.clear(); } vector<int> vcl; for (auto &i:s) { // debug(i, build_hash(i)); vcl.push_back(build_hash(i)); } for (int x = 1; x <= 3; ++x) { for (int i = 1; i <= n; ++i) { (hc[x][i] = 1ll * hc[x][i - 1] * base % mod + x) %= mod; } } cin >> q >> t; build(); bool f = 0; for (auto i:vcl) { if (get() == i) { f = 1; break; } } cout << (f ? "Yes\n" : "No\n"); while (q--) { int l, r; char c; cin >> l >> r >> c; update(l, r, convert(c)); int cur = get(); f = 0; for (auto i:vcl) { if (cur == i) { f = 1; break; } } cout << (f ? "Yes\n" : "No\n"); } } signed main() { ios_base::sync_with_stdio(0); cin.tie(0); p[0] = 1; for (int i = 1; i < maxn; ++i) { p[i] = 1ll * p[i - 1] * base % mod; } solve(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...