Time limit per test: 1.0 seconds

Memory limit: 256 megabytes

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

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

Input

输入具有如下形式:

sql1 r1 z1l2 r2 z2⋮lq rq zq

第一行一个字符串 s。

第二行一个整数 q。

接下来每行:首先两个整数 li,ri (0≤li≤ri<|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。

官方题解:

“考虑离线处理。将所有查询和母串相连建后缀数组。对于每一个查询,在排好序的后缀数组中恰好有一段相对应,可以二分求得 L,R。问题就转换为在 L,R 区间内有多少后缀的下标在查询区间范围内的。这是一个非常经典的区间问题。继续考虑离线处理,从大往小将数插入,然后使用树状数组轻松解决。时间复杂度 O(nlogn)。

事实上本题的做法非常套路,所以过得人也比 F 多(???)。

据验题人说暴力加疯狂特判也能过,而且玄学优化不可卡。暴力姿势太大,比不来。”

Easy部分:KMP暴力

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

Hard部分:

后缀自动机各种不过。应该还是要用后缀数组才行。

我的代码(没过,小数据没问题)

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<memory>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=;
char chr[maxn];
int Le,Ri,Now;
vector<int>G[maxn];
struct SAM
{
int sz,Last,ch[maxn][],slink[maxn],maxlen[maxn],ans;
void init()
{
Last=sz=;G[].clear();
memset(ch[],,sizeof(ch[]));
}
void add(int x)
{
int np=++sz,p=Last;Last=np;
G[np].clear(); memset(ch[np],,sizeof(ch[np]));
maxlen[np]=maxlen[p]+;
while(p&&!ch[p][x]) ch[p][x]=np,p=slink[p];
if(!p) slink[np]=;
else {
int q=ch[p][x];
if(maxlen[q]==maxlen[p]+) slink[np]=q;
else {
int nq=++sz; G[nq].clear();
memcpy(ch[nq],ch[q],sizeof(ch[q]));
G[nq].assign(G[q].begin(),G[q].end());
//G[q].swap(G[nq]);
slink[nq]=slink[q],slink[np]=slink[q]=nq;
maxlen[nq]=maxlen[p]+;
while(p&&ch[p][x]==q) ch[p][x]=nq,p=slink[p];
}
}
while(np>) G[np].push_back(Now),np=slink[np];
}
void solve()
{
scanf("%d%d",&Le,&Ri);
scanf("%s",chr);
int Lt=strlen(chr);
int mp=,Len=;ans=;Le=Le+Lt-;
for(int j=;j<Lt;j++) {
int x=chr[j]-'a';
if(ch[mp][x]) { Len++; mp=ch[mp][x];}
else {
while(mp&&!ch[mp][x]) mp=slink[mp];
if(!mp) { mp=; Len=; }
else { Len=maxlen[mp]+; mp=ch[mp][x]; }
}
}
if(Len==Lt)
for(int i=;i<G[mp].size();i++){
if(G[mp][i]>=Le&&G[mp][i]<=Ri) ans++;
}
printf("%d\n",ans);
}
};
SAM sam;
int main()
{
sam.init(); int q,l;
scanf("%s",chr);
l=strlen(chr);
for(Now=;Now<l;Now++) sam.add(chr[Now]-'a');
scanf("%d",&q);
while(q--) sam.solve();
return ;
}

G 唐纳德与子串(easy)(华师网络赛---字符串,后缀数组)(丧心病狂的用后缀自动机A了一发Easy)的更多相关文章

  1. E比昨天更多的棒棒糖(Easy+Hrad)(华师网络赛)(DP||母函数||背包优化)

    Time limit per test: 2.0 seconds Memory limit: 512 megabytes 唐纳德先生的某女性朋友最近与唐纳德先生同居.该女性朋友携带一 baby.该 b ...

  2. A唐纳德先生和假骰子(华师网络赛)

    Time limit per test: 1.0 seconds Memory limit: 256 megabytes 在进行某些桌游,例如 UNO 或者麻将的时候,常常会需要随机决定从谁开始.骰子 ...

  3. D唐纳德和他的数学老师(华师网络赛)(二分匹配,最大流)

    Time limit per test: 1.0 seconds Memory limit: 256 megabytes 唐纳德是一个数学天才.有一天,他的数学老师决定为难一下他.他跟唐纳德说:「现在 ...

  4. C易位构词(华师网络赛)(错排)

    Time limit per test: 2.0 seconds Memory limit: 256 megabytes 易位构词 (anagram),指将一个单词中的字母重新排列,原单词中的每个字母 ...

  5. 2019CCPC网络赛 C - K-th occurrence HDU - 6704(后缀数组+ST表+二分+主席树)

    题意 求区间l,r的子串在原串中第k次出现的位置. 链接:https://vjudge.net/contest/322094#problem/C 思路 比赛的时候用后缀自动机写的,TLE到比赛结束. ...

  6. Ryuji doesn't want to study 2018徐州icpc网络赛 树状数组

    Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, ea ...

  7. 2019 ICPC南昌邀请赛网络赛比赛过程及题解

    解题过程 中午吃饭比较晚,到机房lfw开始发各队的账号密码,byf开始读D题,shl电脑卡的要死,启动中...然后听到谁说A题过了好多,然后shl让blf读A题,A题blf一下就A了.然后lfw读完M ...

  8. [TyvjP1515] 子串统计 [luoguP2408] 不同子串个数(后缀数组)

    Tyvj传送门 luogu传送门 经典题 统计一个字符串中不同子串的个数 一个字符串中的所有子串就是所有后缀的前缀 先求出后缀数组,求出后缀数组中相邻两后缀的 lcp 那么按照后缀数组中的顺序遍历求解 ...

  9. poj 3261 后缀数组 找反复出现k次的子串(子串能够重叠)

    题目:http://poj.org/problem?id=3261 仍然是后缀数组的典型应用----后缀数组+lcp+二分 做的蛮顺的,1A 可是大部分时间是在调试代码.由于模板的全局变量用混了,而自 ...

随机推荐

  1. Spring IOC(通过实例介绍,属性与构造方法注入)

    概括说明:下面通过实例介绍下属性方法注入.构造方法注入 1.源码结构图 2.代码介绍 (1).Dao接口 :UserDAO (2).Dao接口实现:UserDAOImpl (3).实体类:User ( ...

  2. TP框架---thinkphp中ajax分页

    //点击类别后要显示的内容 public function pagechuli3()//这个方法的功能是根据ajax传过来的值查询数据,再将查询出来的数据返回到ajax,返回的默认是JSON类型. { ...

  3. 【BZOJ3661】Hungry Rabbit 贪心

    [BZOJ3661]Hungry Rabbit Description 可怕的洪水在夏天不期而至,兔子王国遭遇了前所未有的饥荒,它们不得不去外面的森林里寻找食物.为了简化起见,我们假设兔子王国中有n只 ...

  4. Ogbect对象转换为泛型对象

    相信很多人都自己写个这个转换的方法,再次附上我自己的写转换方法仅供参考. T t = BeanUtil.dbObject2Bean(obj, tClass); public static <T& ...

  5. What is the difference between iterations and epochs in Convolution neural networks?

    https://stats.stackexchange.com/questions/164876/tradeoff-batch-size-vs-number-of-iterations-to-trai ...

  6. Redis 配置和使用

    Redis的配置 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者me ...

  7. http 长连接 & 短连接

    1.意义 同一个TCP连接来发送和接收多个HTTP请求/应答,而不是为每一个新的请求/应答打开新的连接的方法. 2.优 较少的CPU和内存的使用 允许请求和应答的HTTP pipelining 降低网 ...

  8. go语言之接口一

    在Go语言中,一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口 我们定义了一个File类,并实现有Read().Write().Seek().Close()等方法.设 想我们有如下接口 ...

  9. JVM 性能优化, Part 4: C4 垃圾回收

    ImportNew注:本文是JVM性能优化 系列-第4篇.前3篇文章请参考文章结尾处的JVM优化系列文章.作为Eva Andreasson的JVM性能优化系列的第4篇,本文将对C4垃圾回收器进行介绍. ...

  10. 关于align-items和align-content的区别和使用场景

    最近在研究flex布局,容器中有两个属性,是用来定义crossAxis测轴排列方式的.一开始接触align-items还可以理解感觉不难,后来看到align-content就感觉有点混淆了,特开一篇博 ...