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

题意: 先输入一个长度为 n 的字符串, 然后有 q 个形如 l, r 的询问, 对于每个询问输出区间 [l, r] 中有多少不同的子串

思路: 后缀自动机模板

代码:

 // 后缀自动机要理解其含义,从起点到每个点的不同路径,就是不同的子串。
// 到每一个点,不同路径,其实就是以这个点为最后一个字符的后缀,长度是介于(p->fa->len,p->len]之间的,个数也就清楚了。
// 而且这个其实是动态变化的,每加入一个字符,就可以知道新加了几个不同子串。
// 加个pos,记录位置,这样就很容易预处理了。 #include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std; const int CHAR = ;
const int MAXN = 2e3 + ; struct SAM_Node{
SAM_Node *fa, *next[CHAR];
int len, id, pos;
SAM_Node(){};
SAM_Node(int _len){
fa = ;
len = _len;
memset(next, , sizeof(next));
}
}; SAM_Node SAM_node[MAXN << ], *SAM_root, *SAM_last;
int SAM_size; SAM_Node *newSAM_Node(int len){
SAM_node[SAM_size] = SAM_Node(len);
SAM_node[SAM_size].id = SAM_size;
return &SAM_node[SAM_size++];
} SAM_Node *newSAM_Node(SAM_Node *p){
SAM_node[SAM_size] = *p;
SAM_node[SAM_size].id = SAM_size;
return &SAM_node[SAM_size++];
} void SAM_init(void){
SAM_size = ;
SAM_root = SAM_last = newSAM_Node();
SAM_node[].pos = ;
} void SAM_add(int x, int len){
SAM_Node *p = SAM_last, *np = newSAM_Node(p->len + );
np->pos = len;
SAM_last = np;
for(; p && !p->next[x]; p = p->fa) p->next[x] = np;
if(!p){
np->fa = SAM_root;
return;
}
SAM_Node *q = p->next[x];
if(q->len == p->len + ){
np->fa = q;
return;
}
SAM_Node *nq = newSAM_Node(q);
nq->len = p->len + ;
q->fa = nq;
np->fa = nq;
for(; p && p->next[x] == q; p = p->fa) p->next[x] = nq;
} void SAM_build(char *s){
SAM_init();
int len = strlen(s);
for(int i = ; i < len; i++){
SAM_add(s[i] - 'a', i + );
}
} int Q[MAXN][MAXN];
char str[MAXN]; int main(void){
int t;
scanf("%d", &t);
while(t--){
scanf("%s", str);
memset(Q, , sizeof(Q));
int n = strlen(str);
for(int i = ; i < n; i++){
SAM_init();
for(int j = i; j < n; j++){
SAM_add(str[j] - 'a', j - i + );
}
for(int j = ; j < SAM_size; j++){
Q[i][SAM_node[j].pos + i - ] += SAM_node[j].len - SAM_node[j].fa->len;
}
for(int j = i + ; j < n; j++){
Q[i][j] += Q[i][j - ];
}
}
int q, l, r;
scanf("%d", &q);
while(q--){
scanf("%d%d", &l, &r);
printf("%d\n", Q[l - ][r - ]);
}
}
return ;
}

hdu4622(后缀自动机模板)的更多相关文章

  1. 牛客网 桂林电子科技大学第三届ACM程序设计竞赛 A.串串-后缀自动机模板题

    链接:https://ac.nowcoder.com/acm/contest/558/A来源:牛客网 A.串串 小猫在研究字符串. 小猫在研究字串. 给定一个长度为N的字符串S,问所有它的子串Sl…r ...

  2. 2018.07.17 后缀自动机模板(SAM)

    洛谷传送门 这是一道后缀自动机的模板题,这道题让我切身体会到了后缀自动机的方便与好写. 代码如下: #include<bits/stdc++.h> #define N 2000005 #d ...

  3. SPOJ 8222. Substrings(后缀自动机模板)

    后缀自动机+dp. 后缀自动机主要是在functioner大牛那里学习的:http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html 这道题是在No_st ...

  4. 后缀自动机模板(SPOJ1811)

    用后缀自动机实现求两个串的最长公共子串. #include <cstdio> #include <algorithm> ; char s[N]; ]; int main() { ...

  5. POJ 1509 Glass Beads 后缀自动机 模板 字符串的最小表示

    http://poj.org/problem?id=1509 后缀自动机其实就是一个压缩储存空间时间(对节点重复利用)的储存所有一个字符串所有子串的trie树,如果想不起来长什么样子可以百度一下找个图 ...

  6. spoj - Longest Common Substring(后缀自动机模板题)

    Longest Common Substring 题意 求两个串的最长公共子串. 分析 第一个串建后缀自动机,第二个串在自动机上跑,对于自动机上的结点(状态)而言,它所代表的最大长度为根结点到当前结点 ...

  7. POJ - 2774 Long Long Message (后缀数组/后缀自动机模板题)

    后缀数组: #include<cstdio> #include<algorithm> #include<cstring> #include<vector> ...

  8. 不在B中的A的子串数量 HDU - 4416 (后缀自动机模板题目)

    题目: 给定一个字符串a,又给定一系列b字符串,求字符串a的子串不在b中出现的个数. 题解: 先将所有的查询串放入后缀自动机(每次将sam.last=1)(算出所有子串个数) 然后将母串放入后缀自动机 ...

  9. 后缀自动机模板——不同子串个数p2408

    后缀自动机的入门博客 https://www.luogu.org/blog/Kesdiael3/hou-zhui-zi-dong-ji-yang-xie 有两种求法,分别对应了两种性质 #includ ...

随机推荐

  1. HDOJ1016(标准dfs)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  2. Jconsole 测试.

    Jconsole 测试. 1 下载并安装 d:\Program Files\Java\jdk1.8.0_111\ JDK自带,Windows下图形界面,监控分析Java程序 2 查看jmx进程号 [r ...

  3. TCG卡牌游戏研究:《炉石战记:魔兽英雄传》所做的改变

    转自:http://www.gameres.com/665306.html TCG演进史 说到卡牌游戏,大家会联想到什么呢? 是历史悠久的扑克牌.风靡全球的<MTG 魔法风云会>与< ...

  4. spring 学习二 @RequestMapping

    RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. RequestMapping注解有六个属性,下面我们把她 ...

  5. [iOS]UIImageView增加圆角

    [iOS]UIImageView增加圆角 "如何给一个UIImageView增加圆角?有几种方法?各自区别?" 备注:本文参考自http://www.jianshu.com/p/d ...

  6. mysql查询最近30天、7天、每天、昨天、上个月的记录

      一些变量说明: add_time为插入的时间 to_days是sql函数,返回的是个天数 data_sub(date,INTERVAL expr type)给指定的日期减去多少天 data()函数 ...

  7. FFmpeg结构体:AVInputFormat

    1.描述 AVInputFormat 是类似COM 接口的数据结构,表示输入文件容器格式,着重于功能函数,一种文件容器格式对应一个AVInputFormat 结构,在程序运行时有多个实例,位于avof ...

  8. Android getWidth和getMeasuredWidth的区别

    getWidth 得到的事某个View的实际尺寸. getMeasuredWidth 得到的是某个View想要在parent view里面占的大小 相比你也见过这样的解释,听起来这样的解释也是云里雾里 ...

  9. 学习Javascript的书籍(转)

    学习Javascript的书籍   作者: 阮一峰 日期: 2008年1月 9日 昨天,ppip同学留言: 你的js主要是用什么材料学的?推荐用哪本教程呢? 我想了一下,发现自己还真的读过不少书.我在 ...

  10. SpringBoot12 QueryDSL02之利用QueryDSL实现多表关联查询

    1 业务需求 有的系统业务逻辑比较复杂,存在着多表关联查询的的情况,查询的内容不仅仅是单张表的的内容而是多张表的字段组合而成的,直接使用SplringDataJPA实现是比较复杂的,但是如果使用Que ...