题意:给出两个字符串,有两个操作,一个是查询从下标 p o s pos pos开始有几个连续相同字符,一个是改变某个字符串中单个字符的值。
题解:线段树
因为查询的是从某个位置开始有几个相同字符,所以在保存和更新时就保存从左端点开始的结果,查询时也要做类似操作。见代码。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#define ll long long
using namespace std;
struct node {
int val;
};
const int maxn = 1e6 + 10;
int t, id, q, pos, idx, len1, len2, len;
char s1[maxn], s2[maxn], x[maxn];
struct ST {
node tree[maxn << 2];
void build(int l, int r, int rt) {
if (l == r) {
if (s1[l] == s2[l]) tree[rt].val = 1;
else tree[rt].val = 0;
}
else {
int mid = (l + r) >> 1;
build(l, mid, rt << 1);
build(mid + 1, r, rt << 1 | 1);
tree[rt].val = tree[rt << 1].val;
if(tree[rt << 1].val == mid - l + 1) tree[rt].val += tree[rt << 1 | 1].val;
}
}
int query(int l, int r, int L, int R, int rt) { //L R 为查询区间
if (r == l) {
return tree[rt].val;
}
int mid = (l + r) >> 1;
int ans = 0;
if (L <= mid) {
ans = query(l, mid, L, R, rt << 1);
if (ans == mid - L + 1) ans += tree[rt << 1 | 1].val;
}
else {
ans = query(mid + 1, r, L, R, rt << 1 | 1);
}
return ans;
}
void update(int pos, int v, int l, int r, int rt) {
if (l == r) {
tree[rt].val = v;
return;
}
int mid = (l + r) >> 1;
if (pos <= mid) {
update(pos, v, l, mid, rt << 1);
}
else {
update(pos, v, mid + 1, r, rt << 1 | 1);
}
tree[rt].val = tree[rt << 1].val;
if (tree[rt << 1].val == mid - l + 1) tree[rt].val += tree[rt << 1 | 1].val;
}
}stree;
int main() {
scanf("%d", &t);
int cas = 1;
while (t--) {
printf("Case %d:\n", cas++);
scanf("%s%s", s1 + 1, s2 + 1);
len1 = strlen(s1 + 1);
len2 = strlen(s2 + 1);
len = max(len1, len2);
stree.build(1, len, 1);
scanf("%d", &q);
while (q--) {
scanf("%d", &id);
if(id == 2){
scanf("%d", &pos);
printf("%d\n", stree.query(1, len, pos + 1, pos + 1, 1));
}
else {
scanf("%d%d%s", &idx, &pos, x);
if (idx == 1) s1[pos + 1] = x[0];
else s2[pos + 1] = x[0];
stree.update(pos + 1, s1[pos + 1] == s2[pos + 1] ? 1 : 0, 1, len, 1);
}
}
}
return 0;
}