题意:给一个长度为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. Git敏捷开发--常用别名

    前言 在Unix下终端开发时,经常会搭配 oh-my-zsh 来使用. oh-my-zsh 中默认内置 git 插件,且支持许多 git alias 的命令,这里对常见的命令进行总结,以供查阅. 常用 ...

  2. Go gRPC进阶-proto数据验证(九)

    前言 上篇介绍了go-grpc-middleware的grpc_zap.grpc_auth和grpc_recovery使用,本篇将介绍grpc_validator,它可以对gRPC数据的输入和输出进行 ...

  3. mybatis源码学习:一级缓存和二级缓存分析

    目录 零.一级缓存和二级缓存的流程 一级缓存总结 二级缓存总结 一.缓存接口Cache及其实现类 二.cache标签解析源码 三.CacheKey缓存项的key 四.二级缓存TransactionCa ...

  4. 博云DevOps 3.0重大升级 | 可用性大幅提升、自研需求管理&自定义工作流上线,满足客户多样化需求

    DevOps能够为企业带来更高的部署频率.更短的交付周期与更快的客户响应速度.标准化.规范化的管理流程,可视化和数字化的研发进度管理和可追溯的版本也为企业带来的了更多的价值.引入DevOps成为企业实 ...

  5. LDA概率主题模型

    目录 LDA 主题模型 几个重要分布 模型 Unigram model Mixture of unigrams model PLSA模型 LDA 怎么确定LDA的topic个数? 如何用主题模型解决推 ...

  6. IntelliJ IDEA在mac中完全删除方法

    cd /Applications/ rm -r IntelliJ\ IDEA.app/ rm -r /Users/apple/Library/Logs/IntelliJIdea2019.3/ rm - ...

  7. 微信自动关闭内置浏览器页面,返回公众号窗口 WeixinJSBridge.call('closeWindow')

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. Spring5参考指南: Resources

    文章目录 内置Resource实现 ResourceLoader ResourceLoaderAware 资源作为依赖 构造ClassPathXmlApplicationContext-快捷方式 资源 ...

  9. 汉字编码对照表(gb2312/Big5/GB2312)

    一.汉字编码的种类 1.GB2312又称国标码,由国家标准总局发布,1981年5月1日实施,通行于大陆.新加坡等地也使用此编码.它是一个简化字的编码规范,当然也包括其他的符号.字母.日文假名等,共74 ...

  10. vuex vue-devtools 安装

    vue-devtools是一款基于chrome游览器的插件,用于调试vue应用,这可以极大地提高我们的调试效率.接下来我们就介绍一下vue-devtools的安装 chrome商店直接安装 谷歌访问助 ...