码迷,mamicode.com
首页 > 编程语言 > 详细

G 唐纳德与子串(华师网络赛---字符串,后缀数组)

时间:2017-12-09 14:00:50      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:参数   使用   head   后缀数组   pac   output   字符   ace   second   

Time limit per test: 1.0 seconds

Memory limit: 256 megabytes

子串的定义是在一个字符串中连续出现的一段字符。这里,我们使用 s[lr] 来表示 s 字符串从 l 到 r(闭区间)的子串。在本题中,字符串下标从 0 开始。显然,对于长度为 n 的字符串共有 n(n+1)2 个子串。

对于一个给定的字符串 s,唐纳德给出 q 次询问,第 i 次询问包括三个参数 li,ri,zi,问在 s[liri] 的所有子串中共有多少个恰好为 zi

技术分享图片

Input

输入具有如下形式:

sql1 r1 z1l2 r2 z2?lq rq zq

第一行一个字符串 s

第二行一个整数 q

接下来每行:首先两个整数 li,ri (0liri<|s|),然后是一个非空字符串 zi。整数和整数,整数和字符串间以单空格隔开。

字符串中只会出现 26 个小写英文字母。

数据规模约定:

  • 对于 Easy 档:1|s|100,q|zi|100
  • 对于 Hard 档:1|s|105,q|zi|105

Output

对于每次询问,输出一个整数,表示答案。

Examples

input

thisisagarbagecompetitionhahaha
5
0 30 a
1 5 is
25 30 hah
6 12 ag
7 12 ag

output

6
2
2
2
1

题意:

给定一个模板串X,求每次给出的匹配串在模板串x特定的位置[L,R]区间出现次数。

自己思路:

小数据,KMP水过。

官方题解:

后缀数组+树状数组。

emmmm,想了会后缀自动机没想出来,GG。

小数据
#include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<memory.h> using namespace std; char a[1000010],b[1000010]; int Next[1000010],L1,L2,ans,x,y; void _next() { int i,k; Next[1]=0; for(i=2,k=0;i<=L2;i++){ while(k&&b[k+1]!=b[i]) k=Next[k]; if(b[k+1]==b[i]) k++; Next[i]=k; } } void _kmp() { _next(); int i,k; ans=0; for(i=x,k=0;i<=y;i++){ while(k&&b[k+1]!=a[i]) k=Next[k]; if(b[k+1]==a[i]) k++; if(k==L2&&i-L2+1>=x) { ans++; k=Next[k]; } } } int main() { int q; scanf("%s",a+1); scanf("%d",&q); L1=strlen(a+1); while(q--){ ans=0; scanf("%d%d",&x,&y); x++;y++; scanf("%s",b+1); L2=strlen(b+1); _next(); _kmp(); printf("%d\n",ans); } return 0; }

 

G 唐纳德与子串(华师网络赛---字符串,后缀数组)

标签:参数   使用   head   后缀数组   pac   output   字符   ace   second   

原文地址:http://www.cnblogs.com/hua-dong/p/8011199.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!