题面描述丢失了。。。

给n个串模板串,然后再给你m个串,对于这m个串的每个串,问在[L,R]的模板串中,在多少个串中出现过;

这题的正解是对于后m个串建AC自动机,然后离线,在fail树上树链求并。

然而我想脑抽地打一下后缀数组;

如果用后缀数组的话,跟喵星球上的点名差不多,但是要在[L,R]中,所以可以用Gty的二逼妹子序列一样的套路,把权值分块而不用树状数组;

这样可以做到nsqrt(n);但是由于串有几百万长,求SA就T了。。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define RG register
using namespace std;
const int N=2000050;
struct data{
int fir,sec,id;
}x[N];
bool cmp(const data &a,const data &b){
if(a.fir==b.fir) return a.sec<b.sec;
else return a.fir<b.fir;
}
int y[N],sa[N],height[N],rnk[N],rk,n,m,len;
int pos[N],fr[N],bel[N],blockans[N],sum[N],st[N],block,block2,L[N],R[N],pre[N],pre2[N],ST[N][21];
int ans[N],lo[N],tong[N],g[N],cnt1,ll[N],rr[N];
struct date{
int l,r,lx,rx,id;
}q[N];
bool Cmp(const date &a,const date &b){
if(pos[a.l]==pos[b.l]) return a.r<b.r;
else return pos[a.l]<pos[b.l];
}
char a[N],s[N];
void work2(){
rk=1;y[x[1].id]=rk;
for(RG int i=2;i<=len;i++){
if(x[i-1].fir!=x[i].fir||x[i-1].sec!=x[i].sec) rk++;
y[x[i].id]=rk;
}
}
void work(){
sort(x+1,x+1+len,cmp);work2();
for(RG int i=1;i<=len;i<<=1){
for(RG int j=1;j+i<=len;j++) x[j].id=j,x[j].fir=y[j],x[j].sec=y[j+i];
for(RG int j=len-i+1;j<=len;j++) x[j].id=j,x[j].fir=y[j],x[j].sec=0;
sort(x+1,x+1+len,cmp);work2();
if(rk==len) break;
}
for(RG int i=1;i<=len;i++) sa[y[i]]=i;
}
void get_height(){
int kk=0;for(int i=1;i<=len;i++) rnk[sa[i]]=i;
for(RG int i=1;i<=len;i++){
if(kk) kk--;
int j=sa[rnk[i]-1];
while(a[i+kk]==a[j+kk]) kk++;
height[rnk[i]]=kk;
}
}
void make_ST(){
pre[0]=1;for(RG int i=1;i<=20;i++) pre[i]=pre[i-1]<<1;
pre2[0]=-1;for(RG int i=1;i<=len;i++) pre2[i]=pre2[i>>1]+1;
for(RG int i=2;i<=len;i++) ST[i][0]=height[i];
for(RG int j=1;j<=20;j++)
for(RG int i=2;i<=len;i++){
if(i+pre[j]-1<=len){
ST[i][j]=min(ST[i][j-1],ST[i+pre[j-1]][j-1]);
}
}
}
int query(int l,int r){
if(l>r) swap(l,r);
int x=pre2[r-l+1];
return min(ST[l][x],ST[r-pre[x]+1][x]);
}
int LCP(RG int l,RG int r){
if(l==r) return len-sa[l];
if(l>r) swap(l,r);
return query(l+1,r);
}
int get_l(RG int x,RG int le){
int ret=x,l=1,r=x;
while(l<=r){
int mid=(l+r)>>1;
if(LCP(x,mid)>=le) ret=mid,r=mid-1;
else l=mid+1;
}
return ret;
}
int get_r(RG int x,RG int le){
RG int ret=x,l=x,r=len;
while(l<=r){
RG int mid=(l+r)>>1;
if(LCP(x,mid)>=le) ret=mid,l=mid+1;
else r=mid-1;
}
return ret;
}
void update(RG int x,RG int val){tong[x]+=val;}
int ask(RG int l,RG int r){
RG int ret=0;
if(bel[l]==bel[r]){
for(RG int i=l;i<=r;i++) if(tong[i]) ret++;
}
else{
for(RG int i=l;i<=rr[bel[l]];i++) if(tong[i]) ret++;
for(RG int i=ll[bel[r]];i<=r;i++) if(tong[i]) ret++;
for(RG int i=bel[l]+1;i<=bel[r]-1;i++) ret+=blockans[i];
}
return ret;
}
void Modui(){
block=sqrt(len);for(RG int i=1;i<=len;i++) pos[i]=(i-1)/block+1;
block2=sqrt(N-1);for(RG int i=1;i<=N-1;i++) bel[i]=(i-1)/block2+1;
if((N-1)%block2) cnt1=(N-1)/block2+1;
else cnt1=(N-1)/block2;
for(RG int i=1;i<=cnt1;i++) ll[i]=(i-1)*block2+1,rr[i]=i*block2;
sort(q+1,q+1+m,Cmp);
for(RG int l=1,r=0,i=1;i<=m;i++){
while(l>q[i].l){l--;update(g[l],1);if(tong[g[l]]==1)blockans[bel[g[l]]]++;}
while(r<q[i].r){r++;update(g[r],1);if(tong[g[r]]==1)blockans[bel[g[r]]]++;}
while(l<q[i].l){update(g[l],-1);if(tong[g[l]]==0)blockans[bel[g[l]]]--;l++;}
while(r>q[i].r){update(g[r],-1);if(tong[g[r]]==0)blockans[bel[g[r]]]--;r--;}
ans[q[i].id]=ask(q[i].lx,q[i].rx);
}
}
int main(){
freopen("substr.in","r",stdin);
freopen("substr.out","w",stdout);
scanf("%d%d",&n,&m);
for(RG int i=1;i<=n;i++){
scanf("%s",s+1);int le=strlen(s+1);
for(RG int j=1;j<=le;j++) a[++len]=s[j],fr[len]=i;
a[++len]='#',fr[len]=N-1;
}
for(RG int i=1;i<=m;i++){
scanf("%d%d",&L[i],&R[i]);scanf("%s",s+1);
int le=strlen(s+1);lo[i]=le;st[i]=len+1;
for(RG int j=1;j<=le;j++) a[++len]=s[j],fr[len]=i+n;
a[++len]='#',fr[len]=N-1;
}
for(RG int i=1;i<=len;i++) x[i].id=i,x[i].fir=x[i].sec=a[i]-'a'+1;
work();get_height();make_ST();
for(RG int i=1;i<=m;i++){
int l=get_l(rnk[st[i]],lo[i]),r=get_r(rnk[st[i]],lo[i]);
q[i].l=l,q[i].r=r,q[i].lx=L[i],q[i].rx=R[i],q[i].id=i;
}
for(RG int i=1;i<=len;i++) g[i]=fr[sa[i]];
Modui();for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
}

  

一道叉姐的AC自动机鬼题的更多相关文章

  1. HDU 2222 AC自动机模板题

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...

  2. HDU 3065 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模 ...

  3. HDU 2896 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串 ...

  4. HDU 2222(AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...

  5. HDU3695(AC自动机模板题)

    题意:给你n个字符串,再给你一个大的字符串A,问你着n个字符串在正的A和反的A里出现多少个? 其实就是AC自动机模板题啊( ╯□╰ ) 正着query一次再反着query一次就好了 /* gyt Li ...

  6. hdu2222 KeyWords Search AC自动机入门题

    /** 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:题意:给定N(N <= 10000)个长度不大于50的模式串,再给定一个长度为L ...

  7. HDu-2896 病毒侵袭,AC自动机模板题!

    病毒侵袭 模板题,不多说了.. 题意:n个不同的字符串分别代表病毒特征,给出m次查询,每次一个字符串(网址),求这个字符串中有几个病毒特征,分别从大到小输出编号,最后输出所有的带病毒网址个数.格式请看 ...

  8. [Bzoj3940] [AC自动机,USACO 2015 February Gold] Censor [AC自动机模板题]

    AC自动机模板题(膜jcvb代码) #include <iostream> #include <algorithm> #include <cstdio> #incl ...

  9. hdu 2222(AC自动机模版题)

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

随机推荐

  1. 九、Hadoop学习笔记————Hive简介

    G级别或者T级别都只能用hadoop

  2. UTF-8和UTF-8无BOM,一个会导致文件中中文变量无法匹配的bug

    昨晚用dom4j中的selectSingleNode解析xml,匹配节点. 发现匹配不到,但是确实存在该节点 将regex改为regex1后则可以匹配,也就是说文件中的"阿里旺旺" ...

  3. idea+scala+spark遇到的一些问题

    1.windows中以本地模式运行spark遇到"Could not locate executable null\bin\winutils.exe in the Hadoop binari ...

  4. .Net Core 2.0 EntityFrameworkCore CodeFirst入门教程

    最近难得有时间闲下来,研究了一下.net core 2.0,总的来说,目前除了一些第三方的库不支持外,基本上可以满足我们的项目需求了! 我们就以一个网站开发为例,搭建一个简单的三层架构,先熟悉一下.n ...

  5. thinkphp实现文件的下载

    首先需要看一下大家使用的Thinkphp的版本,不同的版本使用的方法不同,(在导入公共函数的时候方式不同) 我用的是thinkphp3.2.2版本的,因此直接使用import()函数,直接把使用thi ...

  6. leecode -- 3sum Closet

    Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...

  7. SpringMVC集成Shiro、读取数据库操作权限

    1.Maven添加Shiro所需的jar包 <dependency> <groupId>org.apache.shiro</groupId> <artifac ...

  8. hdu 1496 Equations hash表

    hdu 1496 Equations hash表 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1496 思路: hash表,将原来\(n^{4}\)降 ...

  9. react-native从开始趟的坑

    好多天没更了..... 之前用的华为手机老人机真机调试的,最近几天换了小米,又遇上了坑... 跟之前所有手机一样打开开发者模式,开发者模式是(关于手机--版本号---一直点啊点--退出---辅助功能里 ...

  10. 一键架设FastDFS分布式文件系统脚本,基于Centos6

    一.使用背景 业务驱动技术需要,原来使用 FTP和 Tomcat upload目录的缺陷日渐严重,受限于业务不断扩大,想使用自动化构建,自动化部署,Zookeeper中心化,分布式RPC DUBBO等 ...