HDU4622

Now you are back,and have a task to do:

Given you a string s consist of lower-case English letters only,denote f(s) as the number of distinct sub-string of s.

And you have some query,each time you should calculate f(s[l…r]), s[l…r] means the sub-string of s start from l end at r.

Input

The first line contains integer T(1<=T<=5), denote the number of the test cases.

For each test cases,the first line contains a string s(1 <= length of s <= 2000).

Denote the length of s by n.

The second line contains an integer Q(1 <= Q <= 10000),denote the number of queries.

Then Q lines follows,each lines contains two integer l, r(1 <= l <= r <= n), denote a query.

Output

For each test cases,for each query,print the answer in one line.

Sample Input

2

bbaba

5

3 4

2 2

2 5

2 4

1 4

baaba

5

3 3

3 4

1 4

3 5

5 5

Sample Output

3

1

7

5

8

1

3

8

5

1

题意

给出一个字符串SSS,∣S∣≤2000|S|\leq 2000∣S∣≤2000,给出QQQ组LLL和RRR,Q≤10000Q\leq 10000Q≤10000,求SSS的子串S[L...R]S[L...R]S[L...R],有多少不同的子串。

题解

对于SSS的所有∣S∣|S|∣S∣个后缀,即对(S[i...∣S∣],i∈[1,N])(S[i...|S|],i\in[1,N])(S[i...∣S∣],i∈[1,N])都建立一个后缀自动机。构造过程中,每添加一个字符,根据后缀连接树的性质,从i到当前字符的子串数量为len(u)−len(link(u))len(u)-len(link(u))len(u)−len(link(u)),其中uuu为添加当前字符后的末状态。这样在构造iii到∣S∣|S|∣S∣时就可以求出区间[i,∣S∣][i,|S|][i,∣S∣]的所有子区间的子串数量。而枚举iii就可以求出[1,∣S∣][1,|S|][1,∣S∣]的所有子区间的子串数量了。

AC代码

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<map>
using namespace std;
const int MAXN = 2005;
int n;
char S[MAXN];
struct SAM {
int size, last;
struct Node {
int len, link;
int next[26];
void clear() {
len = link = 0;
memset(next, 0, sizeof(next));
}
} node[MAXN * 2];
void init() {
for (int i = 0; i < size; i++) {
node[i].clear();
}
node[0].link = -1;
size = 1;
last = 0;
}
void insert(char x) {
int ch = x - 'a';
int cur = size++;
node[cur].len = node[last].len + 1;
int p = last;
while (p != -1 && !node[p].next[ch]) {
node[p].next[ch] = cur;
p = node[p].link;
}
if (p == -1) {
node[cur].link = 0;
}
else {
int q = node[p].next[ch];
if (node[p].len + 1 == node[q].len) {
node[cur].link = q;
}
else {
int clone = size++;
node[clone] = node[q];
node[clone].len = node[p].len + 1;
while (p != -1 && node[p].next[ch] == q) {
node[p].next[ch] = clone;
p = node[p].link;
}
node[q].link = node[cur].link = clone;
}
}
last = cur;
}
}sam;
int Ans[MAXN][MAXN];
int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%s", S);
n = strlen(S);
//枚举i
for (int i = 0; i < n; ++i) {
sam.init();
int&& Temp = 0;
//添加字符
for(int j=i;j<n;++j){
sam.insert(S[j]);
Temp += sam.node[sam.last].len;
//如果存在后缀连接边
if (sam.node[sam.last].link != -1) {
Temp -= sam.node[sam.node[sam.last].link].len;
}
//编号从1开始
Ans[i + 1][j + 1] = Temp;
}
}
int Q;
scanf("%d", &Q);
while (Q--) {
int Left, Right;
scanf("%d%d", &Left, &Right);
printf("%d\n", Ans[Left][Right]);
}
}
return 0;
}

Reincarnation的更多相关文章

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

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

  2. hdu 4622 Reincarnation(后缀数组)

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

  3. 字符串(后缀自动机):HDU 4622 Reincarnation

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

  4. 【HDU4622】Reincarnation(后缀自动机)

    [HDU4622]Reincarnation(后缀自动机) 题面 Vjudge 题意:给定一个串,每次询问l~r组成的子串的不同子串个数 题解 看到字符串的大小很小 而询问数太多 所以我们预处理任意的 ...

  5. HDU 4622 Reincarnation Hash解法详解

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

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

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

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

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

  8. 【HDU4622】Reincarnation

    [HDU4622]Reincarnation 一眼似乎不可做,但发现\(strlen(x)\)很小,暴力\(O(n^2)\)预处理每个区间\((l,r)\),查询时\(O(1)\)输出就好了 #inc ...

  9. HDU4622 Reincarnation【SAM】

    HDU4622 Reincarnation 给出一个串,每次询问其一个子串有多少不同的子串 按每个后缀建立\(SAM\)不断往后加字符,然后记录答案,查询的时候直接用即可 //#pragma GCC ...

  10. hdu 4622 Reincarnation

    http://acm.hdu.edu.cn/showproblem.php?pid=4622 用字典树把每一个字符串对应成一个整数 相同的字符串对应到相同的整数上 把所用的串对应的整数放在一个数组里 ...

随机推荐

  1. windows 10 使用Ghost 恢复系统,安装bcd修复引导

    使用windows10安装盘启动,进入系统修复选项,使用cmd X:Source\,那说明进入了管理者模式,然后按照以下步骤依次输入: 1.diskpart 2.sel disk 03.list pa ...

  2. PMP学习笔记 (一)

    1.第一部分 1.1 项目管理的价值观 责任.尊重.公正.诚实 1.2 项目和运营区别 项目:具有独特性.临时性.渐进明细性 运营:具有重复性和持续性 1.3 项目的产出:产品.服务或成果 1.4 滚 ...

  3. [CSP-S2019] Emiya 家今天的饭

    洛咕 题意:原题面见链接,简单来说就是给出一个\(n*m\)的矩阵,每一行代表同一种烹饪方法,每一列代表同一种食材,\(a_{i,j}\)表示使用第i种烹饪方法第j种食材能做出多少种菜,要求至少做一道 ...

  4. [USACO12FEB]Overplanting S

    洛咕 题意:在一个笛卡尔平面坐标系里(X轴向右是正方向,Y轴向上是正方向),有\(N(1<=N<=1000)\)个矩形,第\(i\)个矩形的左上角坐标是\((x1, y1)\),右下角坐标 ...

  5. 动态修改网页的 icon 和 title

    在public的index.html中使用 link 和 title 占位(内容随意,获取到数据之后此处的内容会被覆盖) 在App.vue中调用接口获取数据,找到 link 和 title 元素,将获 ...

  6. 微信公众号 H5授权登录

    首先微信公众号 必须是服务号,订阅号没有 "网页授权获取用户基本信息" 没有这个权限.服务号也必须认证后才有这个权限

  7. Vue项目打包报错 error TS6504

    此处提醒:项目是vite还是vue/cli,打包有区别 打包报错问题: 原因: package.json中,build配置vue-tsc的问题,把对应的命令给删掉: . 语法检查问题: 要么<s ...

  8. fastadmin添加自定义按钮

    问题:关于fastadmin框架列表页面自定义按钮功能 案例:自定义一个同步数据的按钮 <a href="javascript:;" class="btn btn- ...

  9. 维纳攻击 wiener attack

    维纳攻击 wiener attack 目录 维纳攻击 wiener attack 攻击条件 使用原理 十三届全国大学生网络安全竞赛 bd 分析 解答 [羊城杯 2020]rrrrrsa (wiener ...

  10. 拉取docker容器后启动容器的脚本

    我暂且不论如何拉取docker镜像.我使用sudo docker images查看拉取的镜像. 譬如我拉取nvidia的pytorch镜像后,想要创建一个实例或启动某实例,可使用如下脚本(如果本地没有 ...