#include <bits/stdc++.h>
#define fi first
#define se second
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pill pair<int,ll>
#define mem(a, b) memset(a, b, sizeof(a))
#define MASK(i) (1LL << (i))
#define BIT(x, i) (((x) >> (i)) & 1)
#define name "test"
#define int ll
using namespace std;
const int N = 1e6 + 5, base = 311;
const int mod[] = {(int)1e9 + 7, 698912399};
const ll oo = 1e18;
const char d[] = {'J', 'O', 'I'};
template <typename T1, typename T2> bool maxi(T1 &a, T2 b){if (a < b){a = b; return 1;} return 0;}
template <typename T1, typename T2> bool mini(T1 &a, T2 b){if (a > b){a = b; return 1;} return 0;}
int n;
int q;
int a[N][3][2];
int Pow[N][2];
int inv[500];
string t;
vector<string> s(3);
map<pii,bool> check1;
map <string,bool> check2;
vector <pii> HashS;
struct SEGTREE{
int lz[N << 2];
pii val[N << 2];
SEGTREE(){};
pii merge_node(pii a, pii b, int l, int r){
int m = (l + r) >> 1;
int le = m - l + 1;
int r1 = (1ll * a.fi * Pow[le][0] % mod[0] + b.fi) % mod[0];
int r2 = (1ll * a.se * Pow[le][1] % mod[1] + b.se) % mod[1];
return {r1, r2};
}
void build(int id, int l, int r){
lz[id] = -1;
if (l == r){
val[id].fi = val[id].se = t[l];
return;
}
int m = (l + r) >> 1;
build(id << 1, l, m);
build(id << 1 | 1, m + 1, r);
val[id] = merge_node(val[id << 1], val[id << 1 | 1], l, r);
}
void down(int id, int l, int r){
if (lz[id] == -1) return;
val[id].fi = a[r - l + 1][lz[id]][0];
val[id].se = a[r - l + 1][lz[id]][1];
if (l < r){
lz[id << 1] = lz[id];
lz[id << 1 | 1] = lz[id];
}
lz[id] = -1;
}
void update(int id, int l, int r, int u, int v, int x){
down(id, l, r);
if (l > v || r < u) return;
if (l >= u && r <= v){
lz[id] = x;
down(id, l, r);
return;
}
int m = (l + r) >> 1;
update(id << 1, l, m, u, v, x);
update(id << 1 | 1, m + 1, r, u, v, x);
val[id] = merge_node(val[id << 1], val[id << 1 | 1], l, r);
}
} ST;
void load(){
cin.tie(0)->sync_with_stdio(0);
if (fopen(name".inp", "r")){
freopen(name".inp", "r", stdin);
freopen(name".out", "w", stdout);
}
}
void input(){
cin >> n;
for (int i = 0; i < 3; i++)
cin >> s[i];
cin >> q;
cin >> t;
t = " " + t;
}
void crossing(string a){
int H[2];
mem(H, 0);
for (int i = 0; i < n; i++){
int cur = a[i];
for (int j = 0; j < 2; j++)
H[j] = (1ll * H[j] * base % mod[j] + cur) % mod[j];
}
check1[{H[0], H[1]}] = 1;
HashS.push_back({H[0], H[1]});
}
string haha(string a, string b){
string res;
for (int i = 0; i < n; i++){
if (a[i] == b[i]){
res += a[i];
} else {
int cur = 0;
for (int j = 0; j < 3; j++)
if (d[j] != a[i] && d[j] != b[i]) cur = d[j];
res += (char)cur;
}
}
if (check2.find(res) == check2.end()){
// if (res == "JJOI") cout << a << ' ' << b << '\n';
s.push_back(res);
check2[res] = 1;
crossing(res);
}
return res;
}
void solve(){
for (int i = 0; i < 3; i++)
inv[d[i]] = i;
for (int i = 1; i <= n; i++){
for (int j = 0; j < 3; j++){
for (int k = 0; k < 2; k++){
a[i][j][k] = (1ll * a[i - 1][j][k] * base % mod[k] + (int)d[j]) % mod[k];
}
}
}
for (int i = 0; i < (int)s.size(); i++){
check2[s[i]] = 1;
crossing(s[i]);
}
for (int i = 0; i < (int)s.size(); i++){
for (int j = i + 1; j < (int)s.size(); j++){
haha(s[i], s[j]);
}
}
Pow[0][0] = 1;
Pow[0][1] = 1;
for (int i = 1; i < N; i++){
for (int j = 0; j < 2; j++)
Pow[i][j] = 1ll * Pow[i - 1][j] * base % mod[j];
}
ST.build(1, 1, n);
cout << (check1.find(ST.val[1]) == check1.end() ? "No\n" : "Yes\n");
for (int i = 1; i <= q; i++){
int l, r;
char c;
cin >> l >> r >> c;
ST.update(1, 1, n, l, r, inv[c]);
cout << (check1.find(ST.val[1]) == check1.end() ? "No\n" : "Yes\n");
}
}
signed main(){
load();
input();
solve();
}
Compilation message
Main.cpp: In function 'void solve()':
Main.cpp:137:16: warning: array subscript has type 'char' [-Wchar-subscripts]
137 | inv[d[i]] = i;
| ~~~^
Main.cpp:168:38: warning: array subscript has type 'char' [-Wchar-subscripts]
168 | ST.update(1, 1, n, l, r, inv[c]);
| ^
Main.cpp: In function 'void load()':
Main.cpp:88:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
88 | freopen(name".inp", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:89:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
89 | freopen(name".out", "w", stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
68 ms |
79440 KB |
Output is correct |
2 |
Correct |
76 ms |
79616 KB |
Output is correct |
3 |
Correct |
75 ms |
79652 KB |
Output is correct |
4 |
Incorrect |
65 ms |
79448 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
68 ms |
79440 KB |
Output is correct |
2 |
Correct |
76 ms |
79616 KB |
Output is correct |
3 |
Correct |
75 ms |
79652 KB |
Output is correct |
4 |
Incorrect |
65 ms |
79448 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
68 ms |
79440 KB |
Output is correct |
2 |
Correct |
76 ms |
79616 KB |
Output is correct |
3 |
Correct |
75 ms |
79652 KB |
Output is correct |
4 |
Incorrect |
65 ms |
79448 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
68 ms |
79440 KB |
Output is correct |
2 |
Correct |
76 ms |
79616 KB |
Output is correct |
3 |
Correct |
75 ms |
79652 KB |
Output is correct |
4 |
Incorrect |
65 ms |
79448 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |