Query on a string

题意,给定一个大字符串,给定一个小模式串,定义 两种不同的任务模式,分别是查询和更改:

查询对应区间内,有多少个匹配到位的数字;

修改某一位的某一个字母。

于是直觉告诉我们是KMP,而且需要一个单点更新,动态查询的数据结构——直觉上认为树状数组比较合适执行这个任务。

于是,开个大大数组,保存每次匹配时对应位的四字母的匹配指针的位置。

每次扫描到了模式串长度都往树状数组里面存入相关元素。

每次修改之后应当从新就地走一遍模式串,更新相关内容,注意,每次匹配到的新的结果和老结果向同的时候就应当退出。

#include<bits/stdc++.h>
using namespace std; const long long MAXN=;
char str[MAXN];
char str2[];
int lenOfSub;
int flags[MAXN];
int f[MAXN]; int n,m; int tree[MAXN];
void insert(int pos,int key)
{
pos+=;
while(pos<MAXN)
{
tree[pos]+=key;
pos+=pos&(-pos);
}
}
int getSum(int pos)
{
pos+=;
int ret=;
while(pos)
{
ret+=tree[pos];
pos-=pos&(-pos);
}return ret;
} void get_fail()
{
int len=strlen(str2);
lenOfSub=len;
f[]=f[]=;
for(int i=;i<len;++i)
{
int j=f[i];
while(j&&str2[i]!=str2[j])j=f[j];
f[i+]= str2[i]==str2[j]? j+:;
}
}
void get_match()
{
int j=f[];
int len=strlen(str);
for(int i=;i<len;++i)
{
while(j&&str[i]!=str2[j])j=f[j];
j= str[i]==str2[j]? j+:;
flags[i]=j;
}
// for(int i=0;i<len;++i)cout<<flags[i]<<ends;
// cout<<endl;
} void init()
{
scanf("%d\n",&n);
memset(tree,,sizeof(tree));
memset(f,,sizeof(f));
gets(str);
gets(str2);
get_fail();
get_match();
int len=strlen(str);
for(int i=;i<len;++i)
{
if(flags[i]==lenOfSub)insert(i,);
}
for(int it=;it<n;++it)
{
char cm[];
scanf("%s",cm); if(cm[]=='Q')
{
int pos1;int pos2;
scanf("%d%d",&pos1,&pos2);pos1--;pos2--;
int poss=-;int j=f[];
int ans=;
for(int i=pos1;i<=pos2;++i)
{
while(j&&str[i]!=str2[j])j=f[j];
j= str[i]==str2[j]? j+:;
if(j==lenOfSub)ans++;
if(j==flags[i])
{
poss=i;
break;
}
}
if(poss==-)
{
cout<<ans<<"\n";
}else
{
cout<<ans+(getSum(pos2)-getSum(poss))<<"\n";
} }else
{
int pp;
scanf("%d%s",&pp,cm);
pp--;
str[pp]=cm[];
int j=;
if(pp)j=flags[pp-];
for(int i=pp;i<len;++i)
{
while(j&&str[i]!=str2[j])j=f[j];
j= str[i]==str2[j]? j+:;
if(flags[i]==j)break;
if(flags[i]==lenOfSub)insert(i,-);
if(j==lenOfSub)insert(i,);
flags[i]=j;
}
}
} cout<<"\n";
} int main()
{
cin.sync_with_stdio(false); int t;
scanf("%d",&t) ;
while(t--)init(); return ; }

最新文章

  1. bootstrap之clearfix
  2. Hive启动报错: Found class jline.Terminal, but interface was expected
  3. 原生JS编写的照片墙效果实例演示特效
  4. hdu 3311 斯坦纳树
  5. Java反射学习(java reflect)(一)
  6. Qt creator自定义编译运行步骤
  7. for练习--侦察兵
  8. get请求与post请求之间的差异
  9. 微信支付 - iOS
  10. Linux-进程描述(5)之进程环境
  11. Postmark介绍
  12. Spring Tool Suite生成默认的MVC项目的配置文件问题
  13. Qt QLabel 大小随内容自动变化 &amp;&amp; 内容填充整个label空间
  14. PS 制作彩色烟雾
  15. Sudoku POJ - 3076
  16. docker load导入镜像报错:open /var/lib/docker/tmp/docker-import-970689518/bin/json: no such file or directory
  17. Executor, ExecutorService 和 Executors 间的不同
  18. 使用Apache CXF根据wsdl文件生成代码
  19. linux定时删除文件脚本
  20. localhost和本机IP和127.0.0.1之间的区别

热门文章

  1. 安卓usb数据接收
  2. 处理 wait millis 60009, active 50 ,maxactive 200 异常 过程
  3. nodejs入门学习笔记二——解决阻塞问题
  4. Second Highest Salary
  5. Vue汇总(搬砖)
  6. JS案例练习-手机微信聊天对话框
  7. U盘小偷——C++实现U盘插入检测和文件扫描拷贝
  8. HDU5152 线段树 + 数论
  9. leetcode——2
  10. Python开发第二篇