#include const int N = 1000010; using namespace std; // 线段树模板 #define int long long #define ls (u << 1) #define rs (u << 1 | 1) #define mid ((l + r) >> 1) struct Node { int l, r, len; int sum, tag; } tr[N]; int a[N]; int n, m; void pushup(int u) { tr[u].sum = tr[ls].sum + tr[rs].sum; } void build(int u, int l, int r) { tr[u].l = l, tr[u].r = r, tr[u].len = r - l + 1; if (l == r) { tr[u].sum = a[l]; // 初始化线段树 return; } build(ls, l, mid); build(rs, mid + 1, r); pushup(u); } // 向下推送懒标记 void pushdown(int u) { if (tr[u].tag) { tr[ls].tag = tr[rs].tag = tr[u].tag; tr[ls].sum = tr[ls].len * tr[u].tag; tr[rs].sum = tr[rs].len * tr[u].tag; tr[u].tag = 0; // 向下传递懒标记完毕,将父节点的懒标记修改为0 } } // 整体区间赋值为v void modify(int u, int L, int R, int v) { // 整体区间赋值为v int l = tr[u].l, r = tr[u].r; if (l > R || r < L) return; if (l >= L && r <= R) { tr[u].sum = tr[u].len * v; // sum和=区间长度*v tr[u].tag = v; // 懒标记=v return; // 不再继续向下传递 } pushdown(u); // 如果存在懒标记,在分裂前就下传懒标记 modify(ls, L, R, v), modify(rs, L, R, v); pushup(u); } // 区间查询 int query(int u, int L, int R) { int l = tr[u].l, r = tr[u].r; if (l > R || r < L) return 0; if (l >= L && r <= R) return tr[u].sum; pushdown(u); return query(rs, L, R) + query(ls, L, R); } // 将字符映射成数字 int get(char op) { if (op == 'A') return op * 1234; if (op == 'B') return op * 12345; if (op == 'C') return op * 123456; } /*[l,r]之间是不是全是A、B、C? 方法:整数HASH(我给起的名字) 步骤:1、A=1234 B=12345 C=123456 2、如果区间内全是A,则区间长度(r-l+1)*1234=sum 3、如果区间内全是B,则区间长度(r-l+1)*12345=sum 4、如果区间内全是C,则区间长度(r-l+1)*123456=sum */ bool check(int sum, char c, int l, int r) { if (c == 'A') return sum == c * 1234 * (r - l + 1); if (c == 'B') return sum == c * 12345 * (r - l + 1); if (c == 'C') return sum == c * 123456 * (r - l + 1); } signed main() { #ifndef ONLINE_JUDGE freopen("P4979.in", "r", stdin); #endif // 加快读入 ios::sync_with_stdio(false), cin.tie(0); cin >> n; for (int i = 1; i <= n; i++) { char op; cin >> op; a[i] = get(op); } build(1, 1, n); int l, r; cin >> m; while (m--) { char op; cin >> op; if (op == 'A') { // 区间替换操作 char x; cin >> l >> r; cin >> x; // 替换成啥 modify(1, l, r, get(x)); } else { cin >> l >> r; int sum = query(1, l, r); // 区间内是不是都是一样的字符 if ((!check(sum, 'A', l, r) && !check(sum, 'B', l, r) && !check(sum, 'C', l, r))) { puts("No"); continue; } // l=1时,没有前面的内容;r=n时,没有后面的内容,这两种情况,不需要检查是不是前后一致,只需要检查区间内是不是都是一样的即可 if (l == 1 || r == n) { puts("Yes"); continue; } // 执行到这里,肯定是区间内都是一样的,并且,l>1 && r