很有意思的一道题。
不难发觉得关键还是在变化上。
我们用 \(1,2,3\) 表示分别表示三个字母,那么如果 \(c_1\neq c_2\),则 \(c_3 = c_1 \oplus c_2\),直接异或就行。
但是如果 \(c_1=c_2\) 根本表示不了,后面也没法做(罚坐了半个小时
考虑用 \(0,1,2\) 分别表示三个字母,那么我们可以发现 \(c_3\equiv-c_1-c_2\pmod{3}\)。
所以杂交后得到的串 \(S\) 一定可以表示为 \(aS_A+bS_B+cS_C\),由于每一位都是模 \(3\) 意义下的,所以杂交所得的串不会超过 \(27\) 个。
我们直接写个程序爆算所有可能的 \((a,b,c)\),发现只有 \(9\) 种可能。
int f[3][3][3]; int g(int x,int y){return (6 - x - y) % 3;} int main(){ //int T = read();while(T--)solve(); f[1][0][0] = f[0][0][1] = f[0][1][0] = 1; rep(t, 0, 100){ rep(i, 0, 2)rep(j, 0, 2)rep(k, 0, 2)rep(x, 0, 2)rep(y, 0, 2)rep(z, 0, 2) f[g(i, x)][g(j, y)][g(k, z)] |= f[i][j][k] & f[x][y][z]; } rep(i, 0, 2)rep(j, 0, 2)rep(k, 0, 2)if(f[i][j][k])printf("%d, ", i);el; rep(i, 0, 2)rep(j, 0, 2)rep(k, 0, 2)if(f[i][j][k])printf("%d, ", j);el; rep(i, 0, 2)rep(j, 0, 2)rep(k, 0, 2)if(f[i][j][k])printf("%d, ", k);el; return 0; }
那么我们只用预处理这 \(9\) 个串的哈希值,然后用线段树维护 \(T\) 的哈希值,这道题就做完了。
/* Author : SharpnessV Right Output ! & Accepted ! */ #include<bits/stdc++.h> //#define int long long #define rep(i, a, b) for(int i = (a);i <= (b);i++) #define pre(i, a, b) for(int i = (a);i >= (b);i--) #define rp(i, a) for(int i = 1; i <= (a); i++) #define pr(i, a) for(int i = (a); i >= 1; i--) #define go(i, x) for(auto i : x) #define mp make_pair #define pb push_back #define pf push_front #define fi first #define se second #define ze(p) memset(p, 0, sizeof(p)) #define mem(p, x) memset(p, x, sizeof(p)) #define YES puts("Yes") #define NO puts("No") #define si(x) (int)(x).size() #define db cerr #define pc putchar #define el putchar('\n') using namespace std; const double eps = 1e-15, pi = 3.1415926535897932385; typedef long long LL; typedef pair<int,int> Pr; //const int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1}, inf = 0x7fffffff; //char buf[1<<22],*p1=buf,*p2=buf; //#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) inline int read(){ int x = 0;bool f = 1;char ch = getchar(); while(!isdigit(ch))f = ('-' == ch ? 0 : 1), ch = getchar(); while(isdigit(ch))x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar(); if(f)return x;return -x; } inline LL Read(){ LL x = 0;bool f = 1;char ch = getchar(); while(!isdigit(ch))f = ('-' == ch ? 0 : 1), ch = getchar(); while(isdigit(ch))x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar(); if(f)return x;return -x; } int gcd(int x,int y){return y ? gcd(y, x % y) : x;} int lcm(int x,int y){return x / gcd(x, y) * y;} //#define P 1000000007 //#define P 998244353 #define P 998244853 #define bas 229 inline void ad(int &x, int y){x += y; if(x >= P) x -= P;} inline void su(int &x, int y){x -= y; if(x < 0) x += P;} inline void cmn(int &x,int y){if(y < x) x = y;} inline void cmx(int &x,int y){if(y > x) x = y;} inline void cmn(LL &x, LL y){if(y < x) x = y;} inline void cmx(LL &x, LL y){if(y > x) x = y;} int Pow(int x, int y){ if(y < 0)return Pow(Pow(x, P - 2), -y); int now = 1 ; for(;y;y >>= 1, x = 1LL * x * x % P)if(y & 1) now = 1LL * now * x % P; return now; } const int dx[9] = {0, 0, 0, 1, 1, 1, 2, 2, 2}, dy[9] = {0, 1, 2, 0, 1, 2, 0, 1, 2}, dz[9] = {1, 0, 2, 0, 2, 1, 2, 1, 0}; #define N 200005 char s[3][N]; inline int f(int x){if('J' == x)return 0;if('O' == x)return 1;return 2;} int n, m, hs[9], pw[N], pws[N]; struct node{ int l, r, val, tag; }a[N << 2]; #define L a[x].l #define R a[x].r #define ls (x << 1) #define rs (ls | 1) #define S a[x].val #define T a[x].tag void build(int x,int l,int r){ L = l, R = r, T = ~0; if(l == r)S = f(s[0][l]); else{ int mid = (l + r) >> 1; build(ls, l, mid); build(rs, mid + 1, r); S = (1LL * a[ls].val * pw[r - mid] + a[rs].val) % P; } } void pushup(int x, int val){S = 1LL * (T = val) * pws[R - L] % P;} void down(int x){if(~T)pushup(ls, T), pushup(rs, T), T = ~0;} void change(int x,int l,int r,int val){ if(L >= l && R <= r)pushup(x, val); else{ down(x);int mid = (L + R) >> 1; if(mid >= l)change(ls, l, r, val); if(mid < r)change(rs, l, r, val); S = (1LL * a[ls].val * pw[R - mid] + a[rs].val) % P; } } void out(){rep(op, 0, 8)if(a[1].val == hs[op]){YES;return ;}NO;} int main(){ //int T = read();while(T--)solve(); n = read();pw[0] = pws[0] = 1;rp(i, n)pws[i] = pws[i - 1], ad(pws[i], pw[i] = 1LL * pw[i - 1] * bas % P); scanf("%s%s%s", s[0] + 1, s[1] + 1, s[2] + 1); rep(op, 0, 8){ rp(i, n){ int x = dx[op] * f(s[0][i]) + dy[op] * f(s[1][i]) + dz[op] * f(s[2][i]); x %= 3; hs[op] = (1LL * hs[op] * bas + x) % P; } } m = read(); scanf("%s", s[0] + 1); build(1, 1, n); out(); while(m--){ char op[2]; int x = read(), y = read(); scanf("%s", op); change(1, x, y, f(*op)); out(); } return 0; }