[计蒜客16956] Query on a string [2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 G]
2017-09-21 18:15
603 查看
题意
给定字符串S和T两种操作:
1. 修改S串某个位置的字符
2. 询问S某子串中出现了多少次T串
|T|≤10
题解
如果没有修改,我们可以对T建fail指针,然后在S中kmp一遍并记录哪些位置匹配了完整的T串,这相当于一个01数组,询问则是对这个01数组求区间和,可以简单地用树状数组实现。这样一次询问就是O(logn)的。当修改某个字符时,01数组中受到影响的显然最多是10个位置,即每次修改操作暴力kmp并修改对应位置的01数组即可。这样一次修改就是O(logn)的,常数为10左右。于是整体复杂度O(qlogn)。
代码
#include <bits/stdc++.h> #define kN 100010LL #define kL 100010LL #define lb (p&(-p)) int q,n,m,fail[20],C[kL]; bool ok[kL]; char s[kL],t[20]; inline void ins(int p,int w){ for(;p<=n;p+=lb)C[p]+=w; } inline int sum(int p) { int ret=0;for(;p>0;p-=lb)ret+=C[p];return ret; } inline void getfail() { int i, p = 0; fail[1] = 0; for(i=2;i<=m;i++) { while(p&&t[p+1]!=t[i])p=fail[p]; p+=(t[p+1]==t[i]), fail[i] = p; } } inline void Query(int l,int r) { l += m-1; if (l<=r) printf("%d\n",sum(r)-sum(l-1)); else puts("0"); } inline void Change(int p,char c) { if (c == s[p]) return; s[p] = c; int l = p-m+1, r = p+m-1, i; if (l<1) l = 1; if (r > n) r = n; int pos = p; p = 0; for(i = l;i <= r;i ++ ) { while(p && t[p+1]!=s[i]) p = fail[p]; p += (t[p+1]==s[i]); if (i >= pos) { if (p == m) { if (!ok[i]) ok[i]=true,ins(i,1); } else { if (ok[i]) ok[i] = false, ins(i,-1); } } } } inline void work() { int p, i, j, k; char mode, c; scanf("%d%s%s",&q,s+1,t+1); n=strlen(s+1); m=strlen(t+1); getfail(); memset(ok,0,sizeof ok); memset(C,0,sizeof C); p = 0; for(i=1;i<=n;i++) { while(p && t[p+1]!=s[i]) p = fail[p]; p += (t[p+1]==s[i]); if (p == m) ok[i]=true,ins(i,1); } while(q-->0) { while(mode=getchar(),mode!='Q'&&mode!='C'); if (mode == 'Q') { scanf("%d%d",&j,&k); Query(j,k); } else { scanf("%d",&j); while(c=getchar(),c<'!'); Change(j,c); } } puts(""); } int main() { int T; scanf("%d",&T); while(T-->0) work(); return 0; }
相关文章推荐
- 计蒜客 16956 Query on a string(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 G)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 - G Query on a string (KMP+树状数组)
- 【2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 G】Query on a string
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛(G. Query on a string)kmp+线段树
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-G-Query on a string
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 G题 Query on a string
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-G: Query on a string(线段树+预处理)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 Query on a string(字符串+树状数组)
- 2017 ACM-ICPC乌鲁木齐网络赛 G. Query on a string 【KMP+树状数组】
- 2017 ACM-ICPC乌鲁木齐网络赛 G. Query on a string(KMP+树状数组)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 H (简单DP)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 A. Banana
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 G
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 J. Our Journey of Dalian Ends [网络流]
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 Islands
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-C-Coconut
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-A. Banana
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 E. Half-consecutive Numbers
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 C. Coconut