|
|
#include <bits/stdc++.h>
|
|
|
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<n
|
|
|
if (query(1, l - 1, l - 1) != query(1, r + 1, r + 1))
|
|
|
puts("Yes");
|
|
|
else
|
|
|
puts("No");
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
|
} |