[后缀自动机] hihoCoder 1145
Posted kgs719
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[后缀自动机] hihoCoder 1145相关的知识,希望对你有一定的参考价值。
(刷的第一道后缀自动机)
正式开始后缀自动机的漫长道路
hihoCoder 1145
时间限制:10000ms
单点时限:2000ms
内存限制:512MB
描述
小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一个音乐旋律被表示为一段数构成的数列。
现在小Hi想知道一部作品中出现了多少不同的旋律?
输入
共一行,包含一个由小写字母构成的字符串。字符串长度不超过 1000000。
输出
一行一个整数,表示答案。
- 样例输入
-
aab
- 样例输出
- 5
- 思路:
- 对所有状态st求Σ(maxlen(st)-minlen(st))(模板自带-1所以这里不用,到时候更懂的时候补充)
裸题,建完图后直接求就行了
#include<bits/stdc++.h> using namespace std; const int maxn = 1e6+5;; char s[maxn]; struct Sam { int next[maxn << 1][26]; int link[maxn << 1], step[maxn << 1];//step int a[maxn], b[maxn << 1]; int sz, last, root; void init() { //如多次建立自动机,加入memset操作 root = sz = last = 1; } void add(int c) { int p = last; int np = ++sz; last = np; step[np] = step[p] + 1; while(!next[p][c] && p) { next[p][c] = np; p = link[p]; } if(p == 0) { link[np] = root; } else { int q = next[p][c]; if(step[p] + 1 == step[q]) { link[np] = q; } else { int nq = ++sz; memcpy(next[nq], next[q], sizeof(next[q])); step[nq] = step[p] + 1; link[nq] = link[q]; link[q] = link[np] = nq; while(next[p][c] == q && p) { next[p][c] = nq; p = link[p]; } } } } void build() { init(); for(int i = 0; s[i]; i++) { add(s[i] - ‘a‘); } for(int i = 1; i <= sz; i++) { a[step[i]]++; } for(int i = 1; i <= step[last]; i++) { a[i] += a[i - 1]; } for(int i = 1; i <= sz; i++) { b[a[step[i]]--] = i; } } } sam; int main() { cin>>s; long long ans = 0; sam.build(); for(int i = 1;i<=sam.sz;i++) { ans+=sam.step[i]-sam.step[sam.link[i]]; // cout<<ans<<" += "<<sam.step[i]<<" - "<<sam.step[sam.link[i]]<<endl; } cout<<ans<<endl; }
以上是关于[后缀自动机] hihoCoder 1145的主要内容,如果未能解决你的问题,请参考以下文章