博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
牛客 CSL的密码
阅读量:4952 次
发布时间:2019-06-11

本文共 2600 字,大约阅读时间需要 8 分钟。

后缀数组

求本质不同的子串,转换为求本质不同的后缀的前缀,每个后缀贡献的前缀数量减去与上一个重复的前缀即为答案。

#include 
#define INF 0x3f3f3f3f#define full(a, b) memset(a, b, sizeof a)#define __fastIn ios::sync_with_stdio(false), cin.tie(0)#define pb push_backusing namespace std;using LL = long long;inline int lowbit(int x){ return x & (-x); }inline int read(){ int ret = 0, w = 0; char ch = 0; while(!isdigit(ch)){ w |= ch == '-', ch = getchar(); } while(isdigit(ch)){ ret = (ret << 3) + (ret << 1) + (ch ^ 48); ch = getchar(); } return w ? -ret : ret;}template
inline A __lcm(A a, A b){ return a / __gcd(a, b) * b; }template
inline A fpow(A x, B p, C lyd){ A ans = 1; for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd; return ans;}const int N = 200005; int n, m; namespace SuffixArray{ string s; int t[N], t2[N], c[N], sa[N], rank[N], height[N]; void build(int m, int n){ int *x = t, *y = t2; for(int i = 0; i < m; i ++) c[i] = 0; for(int i = 0; i < n; i ++) c[x[i] = s[i]] ++; for(int i = 1; i < m; i ++) c[i] += c[i - 1]; for(int i = n - 1; i >= 0; i --) sa[--c[x[i]]] = i; for(int k = 1; k <= n; k <<= 1){ int p = 0; for(int i = n - k; i < n; i ++) y[p++] = i; for(int i = 0; i < n; i ++){ if(sa[i] >= k) y[p++] = sa[i] - k; } for(int i = 0; i < m; i ++) c[i] = 0; for(int i = 0; i < n; i ++) c[x[y[i]]] ++; for(int i = 1; i < m; i ++) c[i] += c[i - 1]; for(int i = n - 1; i >= 0; i --) sa[--c[x[y[i]]]] = y[i]; swap(x, y); p = 1, x[sa[0]] = 0; for(int i = 1; i < n; i ++){ x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && sa[i - 1] + k < n && sa[i] + k < n && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p ++; } if(p >= n) break; m = p; } int k = 0; for(int i = 0; i < n; i ++) rank[sa[i]] = i; for(int i = 0; i < n; i ++){ if(!rank[i]) continue; if(k) k --; int j = sa[rank[i] - 1]; while(s[i + k] == s[j + k]) k ++; height[rank[i]] = k; } }} using SuffixArray::build;using SuffixArray::height;using SuffixArray::sa; int main(){ __fastIn; cin >> n >> m >> SuffixArray::s; build(128, n); LL ans = 0; for(int i = 0; i < n; i ++){ ans += 1LL * max(0, n - sa[i] - max(height[i], m - 1)); } cout << ans << endl; return 0;}

转载于:https://www.cnblogs.com/onionQAQ/p/11411409.html

你可能感兴趣的文章
【noip2004】虫食算——剪枝DFS
查看>>
Codeforces 40 E. Number Table
查看>>
CLR via C#(第3 版)
查看>>
java语法之final
查看>>
关于响应式布局
查看>>
详解ASP.Net 4中的aspnet_regsql.exe
查看>>
python 多进程和多线程的区别
查看>>
hdu1398
查看>>
[android] 网络断开的监听
查看>>
156.Binary Tree Upside Down
查看>>
MongoDB在windows下安装配置
查看>>
Upselling promotion stored procedure
查看>>
mysql编码配置
查看>>
KVM地址翻译流程及EPT页表的建立过程
查看>>
sigar
查看>>
iOS7自定义statusbar和navigationbar的若干问题
查看>>
c++ 网络编程(一)TCP/UDP windows/linux 下入门级socket通信 客户端与服务端交互代码...
查看>>
程序员如何提高影响力:手把手教你塑造个人品牌
查看>>
身份证校验原理和PHP实现
查看>>
[Locked] Wiggle Sort
查看>>