You have two strings S and T in all capitals.
Now an efficient program is required to maintain a operation and support a query.
The operation C i ch with given integer i and capital letter ch, changes the i-th character of S into ch.
The query Q i j asks the program to find out, in the substring of S from the i-th character to the j-th one, the total number of T appearing.
Input Format
The first line contains an integer T, indicating that there are T test cases.
For each test case, the first line contains an integer N (N≤100000).
The second line is the string S (∣S∣≤100000) and the third line is the string T (∣T∣≤10).
Each of the following N lines provide a operation or a query as above descriptions.
Output Format
For each query, output an integer correponding to the answer.
Output an empty line after each test case.
样例输入
1 5 AABBABA AA Q 1 3 C 6 A Q 2 7 C 2 B Q 1 5
样例输出
1 2 0
题目来源
串S, T(len(T) <= 10)Q l r 询问S[l ,r]中T出现次数,可以重复计算
C i ch 更新S[i] = ch
典型的单点更新,区间询问。
1、算头不算尾 ;
2、单点更新: S[i]= ch ,影响 [i-len(T)+1 , i] 区间
暴力更新单点
#include <string>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <set>
#include <iostream>
#include <algorithm>
#include <map>
#include <queue>
#include <math.h>
#include <iostream>
#include <set>
using namespace std;
typedef long long LL ;
const int N = 100008 ;
int sum[N<<2] ;
int pos[N] ;
void build(int l, int r, int t) {
if(l == r) {
sum[t] = pos[l] ;
return ;
}
int m = (l + r) >> 1 ;
build(l, m, t<<1);
build(m+1, r, t<<1|1);
sum[t] = sum[t<<1] + sum[t<<1|1] ;
}
int query(int L, int R, int l, int r, int t) {
if(L <= l && r <= R) {
return sum[t] ;
}
int reslut = 0 ;
int m = (l + r) >> 1 ;
if(L <= m) {
reslut += query(L, R, l, m, t<<1) ;
}
if(R > m) {
reslut += query(L, R, m+1, r, t<<1|1) ;
}
return reslut ;
}
void update(int i, int c, int l, int r, int t) {
if(l == r) {
sum[t] = c ;
return ;
}
int m = (l + r) >> 1 ;
if(i <= m) {
update(i, c, l, m, t<<1) ;
} else {
update(i, c, m+1, r, t<<1|1) ;
}
sum[t] = sum[t<<1] + sum[t<<1|1] ;
}
char text[N], word[20] ;
int n, m ;
int match(int textBegin) {
if(textBegin + m - 1 > n - 1) {
return 0 ;
}
for(int i = 0 ; i < m ; i++) {
if(word[i] != text[textBegin + i]) {
return 0 ;
}
}
return 1 ;
}
int main() {
int t, q, k , l , r ;
char c[3] ;
scanf("%d", &t) ;
while(t-- > 0) {
scanf("%d", &q) ;
scanf("%s", text) ;
scanf("%s", word) ;
n = strlen(text) ;
m = strlen(word) ;
for(int i = 0 ; i < n ; i++) {
pos[i] = match(i) ;
}
if(n >= m) {
build(0, n-m, 1) ;
}
while(q-- > 0) {
scanf("%s", c) ;
if(c[0] == 'Q') {
scanf("%d%d", &l, &r) ;
if(n < m) {
printf("%d\n", 0) ;
continue ;
}
l-- ;
r-- ;
if(l > r) {
std::swap(l, r) ;
}
r = r - m + 1 ;
int reslut = 0 ;
if(l <= r) {
reslut = query(l, r, 0, n-m, 1) ;
}
printf("%d\n", reslut) ;
} else {
scanf("%d", &k) ;
k-- ;
scanf("%s", c) ;;
text[k] = c[0] ;
if(n < m) {
continue ;
}
int l = std::max(0, k-m+1) ;
int r = std::min(k, n-m) ;
for(int i = l ; i <= r ; i++) {
update(i, match(i), 0, n-m, 1) ;
}
}
}
printf("\n") ;
}
return 0 ;
}