【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=4622

【题目大意】

  给出一个长度不超过2000的字符串,有不超过10000个询问,问【L,R】子串中出现的子串数目,相同子串不可重复计数。

【题解】

  考虑到字符串长度只有两千,我们对每个位置往后建立2000个后缀自动机,
  这样子就能分别计算每个位置往后出现的字符串数目并保存,
  对于sam上的一个节点来说,它的匹配长度与失配位置的匹配长度只差就是他们之间的子串,
  所以,我们在建立sam可以同时计算出现的子串数目。

【代码】

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N=4005;
char s[N];
struct sam{
int p,q,np,nq,cnt,last,tot,a[N][26],l[N],f[N];
sam(){tot=cnt=0;last=++cnt;}
int val(int c){return l[c]-l[f[c]];}
void init(){
tot=cnt=0;last=++cnt;
memset(a,0,sizeof(a));
memset(l,0,sizeof(l));
memset(f,0,sizeof(f));
}
int val(int c){return l[c]-l[f[c]];}
void extend(int c){
p=last;np=last=++cnt;l[np]=l[p]+1;
while(!a[p][c]&&p)a[p][c]=np,p=f[p];
if(!p){f[np]=1;tot+=val(np);}
else{
q=a[p][c];
if(l[p]+1==l[q]){f[np]=q;tot+=val(np);}
else{
nq=++cnt;l[nq]=l[p]+1;
memcpy(a[nq],a[q],sizeof(a[q]));
tot-=val(p)+val(q);
f[nq]=f[q]; f[np]=f[q]=nq;
tot+=val(p)+val(q)+val(np)+val(nq);
while(a[p][c]==q)a[p][c]=nq,p=f[p];
}
}
}int ans[2005][2005];
void CalAns(){
scanf("%s",s+1);
int len=strlen(s+1);
for(int i=1;i<=len;i++){
init();
for(int j=i;j<=len;j++){
extend(s[j]-'a');
ans[i][j]=tot;
}
}
}
void solve(){
int Q,l,r;
scanf("%d",&Q);
while(Q--){
scanf("%d%d",&l,&r);
printf("%d\n",ans[l][r]);
}
}
}sam;
int main(){
int T;
scanf("%d",&T);
while(T--){
sam.CalAns();
sam.solve();
}return 0;
}

  

HDU 4622 Reincarnation(后缀自动机)的更多相关文章

  1. HDU 4622 Reincarnation 后缀自动机 // BKDRHash(最优hash)

    Reincarnation Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) P ...

  2. HDU 4622 Reincarnation 后缀自动机

    模板来源:http://blog.csdn.net/zkfzkfzkfzkfzkfzkfzk/article/details/9669747 解法参考:http://blog.csdn.net/dyx ...

  3. Hdu 4622 Reincarnation(后缀自动机)

    /* 字符串长度较小, 可以离线或者直接与处理所有区间的答案 动态加入点的时候, 因为对于其他点的parent构造要么没有影响, 要么就是在两个节点之间塞入一个点, 对于minmax的贡献没有改变 所 ...

  4. Reincarnation HDU - 4622 (后缀自动机)

    Reincarnation \[ Time Limit: 3000 ms\quad Memory Limit: 65536 kB \] 题意 给出一个字符串 \(S\),然后给出 \(m\) 次查询, ...

  5. hdu 4622 Reincarnation(后缀数组)

    hdu 4622 Reincarnation 题意:还是比较容易理解,给出一个字符串,最长2000,q个询问,每次询问[l,r]区间内有多少个不同的字串. (为了与论文解释统一,这里解题思路里sa数组 ...

  6. HDU 4622 Reincarnation Hash解法详解

    今天想学字符串hash是怎么弄的.就看到了这题模板题 http://acm.hdu.edu.cn/showproblem.php?pid=4622 刚开始当然不懂啦,然后就上网搜解法.很多都是什么后缀 ...

  7. HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)

    Reincarnation Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  8. hdu 4622 Reincarnation SAM模板题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给定一个长度不超过2000的字符串,之后有Q次区间查询(Q <= 10000),问区 ...

  9. HDU 6583 Typewriter(后缀自动机)

    Typewrite \[ Time Limit: 1500 ms\quad Memory Limit: 262144 kB \] 题意 给出一个字符串 \(s\),现在你需要构造出这个字符串,你每次可 ...

随机推荐

  1. Linux命令之ifconfig

    许多windows非常熟悉ipconfig命令行工具,它被用来获取网络接口配置信息并对此进行修改.Linux系统拥有一个类似的工具,也就是ifconfig(interfaces config).通常需 ...

  2. MySQL数据库mysqlcheck的使用方法

    MySQL数据库mysqlcheck的使用方法的相关知识是本文我们主要要介绍的内容,我们知道,mysqlcheck,是mysql自带的可以检查和修复MyISAM表,并且它还可以优化和分析表,mysql ...

  3. jq方法

    DOM属性-获取和设置页面元素的DOM属性 .addClass()..attr()..prop()..hasClass()..html()..removeAttr()..removeClass().. ...

  4. css3 drop-shaow阴影效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  5. 航频卫士APP截图

  6. c/c++:内存泄露和野指针的概念

    内存泄漏 用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元.直到程序结束.即所谓内存泄漏.    注意:内存泄漏是指堆内存的泄漏. 简单的说就是申请了一块内存空间,使用 ...

  7. vim note

    2016-1-22 vim plugin collections: (参考 https://www.youtube.com/watch?v=0QFR-_wUoA0) vim-pathogen  插件管 ...

  8. iPhone/iTouch免99美刀真机调试

    本文经本人验证,攻略来源于网上,由于多次转载原始出处不可靠,故无法对原作者进行链接引用,抱歉. 本文仅为记录流程,以备日后查询.本文版权所无,欢迎转载和拍砖. 测试环境: XCode 4.0.2 + ...

  9. 使用rowid和rownum获取记录时要注意的问题

    我们知道.rowid和rownum在Oracle中都是能够被当做伪劣使用的,主要用来定位表中特定的记录,但它们是有差别的,rowid是和行记录的物理地址相应的.而rownum则不是,是通过返回的记录集 ...

  10. .net 文件下载

    /** 输入参数* _Request: Page.Request 对象* _Response: Page.Response 对象* _fileName: 下载文件名* _fullPath: 带文件名下 ...