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
题目来源
题意:操作1询问l到r中有几个子串,操作2变化一个字母。。
POINT:
这种操作次数很多的用树状数组来做,sum[a]代表以a结尾的子串是不是要的子串。
每次变化更新就行了。
代码:
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <string>
typedef long long LL;
using namespace std;
const int maxn = 100000+5;
int nxt[10+5];
int sum[maxn];
int a[maxn];
void prekmp(char s[],int l)
{
int i,j;
i=0;
j=nxt[0]=-1;
while(i<l)
{
while(j!=-1&&s[i]!=s[j]) j=nxt[j];
nxt[++i]=++j;
}
}
int lowbit(int x)
{
return x&-x;
}
int ll;
void add(int now,int k)
{
for(int i=now;i<=ll;i+=lowbit(i))
{
sum[i]+=k;
}
}
int query(int now)
{
int ans=0;
for(int i=now;i>=1;i-=lowbit(i))
{
ans+=sum[i];
}
return ans;
}
void kmp(char x[],int l,char s[],int k)
{
int i=0,j=0;
int ans=0;
while(i<l)
{
while(j!=-1&&x[i]!=s[j]) j=nxt[j];
j++;
i++;
if(j==k)
{
a[i]=1;
add(i,1);
j=nxt[j];//可以重叠
}
}
}
int main()
{
int T;scanf("%d",&T);
char x[maxn];
char s[10+5];
while(T--)
{
memset(a,0,sizeof a);
memset(sum,0,sizeof sum);
int n;scanf("%d",&n);
scanf("%s",x);
scanf("%s",s);
ll=(int)strlen(x);
int lll=(int)strlen(s);
prekmp(s,lll);
kmp(x,ll,s,lll);
while(n--)
{
char s1[2];
scanf("%s",s1);
if(s1[0]=='Q')
{
int l,r;
scanf("%d %d",&l,&r);
if(l+lll-1>r) printf("0\n");
else
printf("%d\n",query(r)-query(l+lll-2));
}
else
{
int p;
scanf("%d %s",&p,s1);
x[p-1]=s1[0];
for(int i=p-1;i<=p+lll-2;i++)
{
if(i+1<lll) continue;
int j;
int now=lll-1;
for(j=i;j>=i-lll+1;j--)
{
if(x[j]==s[now])
{
now--;
}
else
break;
}
if(j==i-lll)
{
if(a[i+1]==0)
add(i+1,1),a[i+1]=1;
}
else
{
if(a[i+1]==1)
add(i+1,-1),a[i+1]=0;
}
}
}
}
printf("\n");
}
}