2017 ACM-ICPC乌鲁木齐网络赛 G. Query on a string(KMP+树状数组)

题目链接:https://www.jisuanke.com/contest/870

题意:

给出两个字符串S和T,Q次操作:①C a b表示将第a个字符改为b;②Q l r表示T在S的子串[l, r]中共出现多少次

其中|S|<=100000,|T|<=10,Q<=100000

思路:

若S串的子串[x-|T|+1, x]和T串完美匹配,那么flag[x]==1,否则flag[x]==0,sum[]是flag[]的前缀和

这样每次查询区间[l, r]答案就是sum[r]-sum[l+|T|-2],注意特判r<l+|T|-2的情况

用树状数组维护就好

又因为|T|<10,所以每次修改影响的范围很小,可以直接暴力

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
char str[100005], jud[100005];
int n, nj[100005], ns[100005];
LL tre[100005];
void Update(int x, int val)
{
	while(x<=n)
	{
		tre[x] += val;
		x += x&-x;
	}
}
LL Query(int x)
{
	LL sum = 0;
	while(x)
	{
		sum += tre[x];
		x -= x&-x;
	}
	return sum;
}
int main(void)
{
	char ch[15];
	int T, Q, m, p, q, L, R;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d%s%s", &Q, str+1, jud+1);
		n = strlen(str+1);
		m = strlen(jud+1);
		p = 0, q = 1;
		memset(nj, 0, sizeof(nj));
		memset(tre, 0, sizeof(tre));
		memset(ns, 0, sizeof(ns));
		while(q<=m)
		{
			if(p==0 || jud[p]==jud[q])
			{
				p++, q++;
				if(jud[p]==jud[q])
					nj[q] = nj[p];
				else
					nj[q] = p;
			}
			else
				p = nj[p];
		}
		p = q = 1;
		while(p<=n)
		{
			while(str[p]!=jud[q] && q>=1)
				q = nj[q];
			if(q==0)
			{
				ns[p] = 0;
				p++, q++;
				continue;
			}
			ns[p++] = q++;
			if(q==m+1)
			{
				Update(p-1, 1);
				q = nj[q];
			}
		}
		while(Q--)
		{
			scanf("%s", ch);
			if(ch[0]=='Q')
			{
				scanf("%d%d", &L, &R);
				if(L+m-1>R)
					printf("0\n");
				else
					printf("%lld\n", Query(R)-Query(L+m-2));
			}
			else
			{
				scanf("%d%s", &R, ch);
				p = max(R-15, 0), q = ns[p];
				str[R] = ch[0];
				while(p<=R+15 && p<=n)
				{
					while(str[p]!=jud[q] && q>=1)
						q = nj[q];
					if(q==0)
					{
						if(ns[p]==m)
							Update(p, -1);
						ns[p] = 0;
						p++, q++;
						continue;
					}
					if(ns[p]==m)
						Update(p, -1);
					ns[p++] = q++;
					if(q==m+1)
					{
						Update(p-1, 1);
						q = nj[q];
					}
				}
			}
		}
		printf("\n");
	}
	return 0;
}
原创文章 1134 获赞 1439 访问量 61万+

猜你喜欢

转载自blog.csdn.net/Jaihk662/article/details/77916799