Submission #541194

#TimeUsernameProblemLanguageResultExecution timeMemory
541194JomnoiCrossing (JOI21_crossing)C++17
100 / 100
222 ms14288 KiB
#include <bits/stdc++.h> #define DEBUG 0 using namespace std; const int N = 2e5 + 10; const int P = 31; const int MOD = 1e9 + 7; string pat = "JOI"; long long bn[N], qs[N]; long long get_hash(string s) { long long H = 0; int n = s.length(); for(int i = 0; i < n; i++) { H = (H * P + s[i]) % MOD; } return H; } string crossing(string s, string t) { string res = ""; int n = s.length(); for(int i = 0; i < n; i++) { if(s[i] == t[i]) { res += s[i]; continue; } for(int j = 0; j < 3; j++) { if(s[i] != pat[j] and t[i] != pat[j]) { res += pat[j]; break; } } } return res; } class SegmentTree { private : long long tree[4 * N]; char lazy[4 * N]; public : long long merge(long long L, long long R, int l, int r) { int mid = (l + r) / 2; long long res = (L * bn[r - mid + 1] + R) % MOD; return res; } void build(int idx, int l, int r) { lazy[idx] = '*'; if(l == r) { char t0; cin >> t0; tree[idx] = t0; return; } int mid = (l + r) / 2; build(idx * 2, l, mid); build(idx * 2 + 1, mid + 1, r); tree[idx] = merge(tree[idx * 2], tree[idx * 2 + 1], l, r); } void push(int idx, int l, int r) { if(lazy[idx] == '*') { return; } tree[idx] = (qs[r - l + 1] * lazy[idx]) % MOD; if(l != r) { lazy[idx * 2] = lazy[idx * 2 + 1] = lazy[idx]; } lazy[idx] = '*'; } void update(int idx, int l, int r, int ql, int qr, char c) { push(idx, l, r); if(r < ql or qr < l) { return; } if(ql <= l and r <= qr) { lazy[idx] = c; push(idx, l, r); return; } int mid = (l + r) / 2; update(idx * 2, l, mid, ql, qr, c); update(idx * 2 + 1, mid + 1, r, ql, qr, c); tree[idx] = merge(tree[idx * 2], tree[idx * 2 + 1], l, r); } long long get_ans() { return tree[1]; } void print(int idx, int l, int r) { push(idx, l, r); cout << l << " - " << r << " : " << tree[idx] << '\n'; if(l == r) { return; } int mid = (l + r) / 2; print(idx * 2, l, mid); print(idx * 2 + 1, mid + 1, r); } }ST; int main() { cin.tie(0)->sync_with_stdio(0); int n; cin >> n; bn[1] = 1; qs[1] = 1; for(int i = 2; i <= n; i++) { bn[i] = (bn[i - 1] * P) % MOD; qs[i] = (qs[i - 1] + bn[i]) % MOD; } string s[6]; cin >> s[0] >> s[1] >> s[2]; set <long long> Hash; for(int i = 0; i < 3; i++) { Hash.insert(get_hash(s[i])); if(DEBUG) { cout << s[i] << ' ' << get_hash(s[i]) << '\n'; } } for(int i = 0; i < 3; i++) { for(int j = i + 1; j < 3; j++) { s[2 + i + j] = crossing(s[i], s[j]); if(DEBUG) { cout << s[2 + i + j] << ' ' << get_hash(s[2 + i + j]) << '\n'; } Hash.insert(get_hash(s[2 + i + j])); } } for(int i = 3; i < 6; i++) { for(int j = i + 1; j < 6; j++) { if(DEBUG) { cout << crossing(s[i], s[j]) << ' ' << get_hash(crossing(s[i], s[j])) << '\n'; } Hash.insert(get_hash(crossing(s[i], s[j]))); } } int q; cin >> q; ST.build(1, 0, n - 1); // input string t0 if(DEBUG) { ST.print(1, 0, n - 1); cout << ST.get_ans() << " : "; } if(Hash.count(ST.get_ans())) { cout << "Yes\n"; } else { cout << "No\n"; } while(q--) { int l, r; char c; cin >> l >> r >> c; ST.update(1, 0, n - 1, l - 1, r - 1, c); if(DEBUG) { ST.print(1, 0, n - 1); cout << ST.get_ans() << " : "; } if(Hash.count(ST.get_ans())) { cout << "Yes\n"; } else { cout << "No\n"; } } 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...