You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
3.7 KiB

2 years ago
#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
1A=1234 B=12345 C=123456
2A(r-l+1)*1234=sum
3B(r-l+1)*12345=sum
4C(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;
}