题意:给一个长度为2000的字符串,10000次询问区间[L,R]内的不同子串的个数

思路:对原串的每个前缀求一边后缀数组,询问[L,R]就变成了询问[L,n]了,即求一个后缀里面出现了多少个不同子串。于是对所有大于等于L的后缀统计一遍即可。

  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a)) typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull; #ifndef ONLINE_JUDGE
void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
#endif
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
template<typename T>
void V2A(T a[],const vector<T>&b){for(int i=;i<b.size();i++)a[i]=b[i];}
template<typename T>
void A2V(vector<T>&a,const T b[]){for(int i=;i<a.size();i++)a[i]=b[i];} const double PI = acos(-1.0);
const int INF = 1e9 + ; /* -------------------------------------------------------------------------------- */ const int maxn = 2e3 + ; struct SA {
//const static int maxn = 2e3 + 7;
int sa[maxn], t[maxn], t2[maxn], c[maxn], n, m;
int Rank[maxn], Height[maxn];
int s[maxn]; void init(int n, int m, char s[]) {
for (int i = ; i < n; i ++) this->s[i] = s[i];
this->s[n] = ;
this->n = n + ;
this->m = m;
} void build() {
int i, *x = t, *y = t2;
for (i = ; i < m; i ++) c[i] = ;
for (i = ; i < n; i ++) c[x[i] = s[i]] ++;
for (i = ; i < m; i ++) c[i] += c[i - ];
for (i = n - ; i >= ; i --) sa[-- c[x[i]]] = i;
for (int k = ; k <= n; k <<= ) {
int p = ;
for (i = n - k; i < n; i ++) y[p ++] = i;
for (i = ; i < n; i ++) if (sa[i] >= k) y[p ++] = sa[i] - k;
for (i = ; i < m; i ++) c[i] = ;
for (i = ; i < n; i ++) c[x[y[i]]] ++;
for (i = ; i < m; i ++) c[i] += c[i - ];
for (i = n - ; i >= ; i --) sa[-- c[x[y[i]]]] = y[i];
swap(x, y);
p = ; x[sa[]] = ;
for (i = ; i < n; i ++) {
x[sa[i]] = y[sa[i - ]] == y[sa[i]] &&
y[sa[i - ] + k] == y[sa[i] + k]? p - : p ++;
}
if (p >= n) break;
m = p;
}
}
void getHeight() {
int i, k = ;
for (i = ; i < n; i ++) Rank[sa[i]] = i;
for (i = ; i < n; i ++) {
if (k) k --;
int j = sa[Rank[i] - ];
while (s[i + k] == s[j + k]) k ++;
Height[Rank[i]] = k;
}
}
};
SA sa;
int H[maxn][maxn], S[maxn][maxn];
char s[maxn]; int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int T, m;
cin >> T;
while (T --) {
scanf("%s", s);
for (int i = ; s[i]; i ++) {
sa.init(i + , , s);
sa.build();
sa.getHeight();
copy(H[i], sa.Height);
copy(S[i], sa.sa);
} cin >> m;
while (m --) {
int u, v;
scanf("%d%d", &u, &v);
int *ph = H[v - ], *ps = S[v - ], common = , ans = ;
u --;
for (int i = ; i <= v; i ++) {
if (ps[i] >= u) {
ans += v - ps[i] - common;
common = INF;
}
umin(common, ph[i + ]);
}
printf("%d\n", ans);
}
}
return ;
}

[hdu4622 Reincarnation]后缀数组的更多相关文章

  1. HDU-4622 Reincarnation 后缀数组 | Hash,维护和,扫描

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给一个字符串,询问某字串的不同字串的个数. 可以用后缀数组来解决,复杂度O(n).先求出倍 ...

  2. HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)

    Problem Description Now you are back,and have a task to do: Given you a string s consist of lower-ca ...

  3. hdu 4622 Reincarnation(后缀数组)

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

  4. 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)

    模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...

  5. HDU4622 Reincarnation【SAM】

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

  6. 后缀数组的倍增算法(Prefix Doubling)

    后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...

  7. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  8. BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]

    1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1383  Solved: 582[Submit][St ...

  9. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

随机推荐

  1. 【JAVA】并发-基础IO

    一.java.io包支持.java的IO流有输入.输出两种,每种输入.输出流又可分为字节流.字符流两大类,字节流以字节为单位处理IO操作,字符流以字符为单位处理IO操作 JDK 1.4以后有java. ...

  2. JavaScript基础笔记1220

    JavaScript笔记1.JavaScript关键词2.JavaScript标识符 必须以字母,下划线(_)或美元符($)开始. 后续的字符可以是字母.数字.下划线或者美元符 (数字是不允许作为首字 ...

  3. 今天我们来谈谈jquery,

    ---恢复内容开始--- 首先从jquery的两种写法开始: 1.$(document).ready(function(){}); 首先我们的jquery是用来操作DOM节点的,所以必须等到文档加载完 ...

  4. python机器学习入门-(1)

    机器学习入门项目 如果你和我一样是一个机器学习小白,这里我将会带你进行一个简单项目带你入门机器学习.开始吧! 1.项目介绍 这个项目是针对鸢尾花进行分类,数据集是含鸢尾花的三个亚属的分类信息,通过机器 ...

  5. TensorFlow keras dropout层

    # 建立神经网络模型 model = keras.Sequential([ keras.layers.Flatten(input_shape=(28, 28)), # 将输入数据的形状进行修改成神经网 ...

  6. 数据结构(C语言版)---查找

    1.查找表:同一类型的数据元素构成的集合. 2.对查找表进行的操作:查询某特定元素.检索满足条件的元素的属性.插入元素.删除元素. 1)若对查找表进行的操作只涉及前两种,则为静态查找表:需要进行插入和 ...

  7. 一图了解redis

    了解redis,这一张图就够了,话不多说,看图: 版权所有,转载请注明出处,欢迎讨论交流

  8. 面试题56 - I. 数组中数字出现的次数

    面试题56 - I. 数组中数字出现的次数 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 示例 ...

  9. /sbin/mount.vboxsf: mounting failed with the error: Protocol error

    公司换了新电脑,需要把之前的虚拟机的配置全部备份下来,在移动的过程中挂载共享文件夹时候出现了 /sbin/mount.vboxsf: mounting failed with the error: P ...

  10. Adobe Flash player 过期

    完美解决问题的办法,在百度中输入 "adobe flash player debugger",如图进入官网 选择对应操作系统的对应版本,下载安装,重启浏览器,一切ok IE内核浏览 ...