Luogu P2408 不同子串个数【SAM】
P2408 不同子串个数
计算一个字符串的不同子串个数
两种方法,一种是\(dp\)出来\(SAM\)从起点开始的路径数量
另一种方法就是计算每个点的\(len[i]-len[link[i]]\)这个计算的就是这个等价类的不同串的数量
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 2e5+7;
using LL = int_fast64_t;
struct SAM{
int len[MAXN],link[MAXN],tot,ch[MAXN][26],last;
LL f[MAXN];
void init(){ tot = last = 0; link[tot] = -1; memset(ch,0,sizeof(ch)); memset(f,0,sizeof(f)); }
void extend(int c){
int np = ++tot, p = last;
len[np] = len[p] + 1;
while(p!=-1 and !ch[p][c]){
ch[p][c] = np;
p = link[p];
}
if(p==-1) link[np] = 0;
else{
int q = ch[p][c];
if(len[p]+1==len[q]) link[np] = q;
else{
int clone = ++tot;
len[clone] = len[p] + 1;
link[clone] = link[q];
memcpy(ch[clone],ch[q],sizeof(ch[q]));
link[np] = link[q] = clone;
while(p!=-1 and ch[p][c]==q){
ch[p][c] = clone;
p = link[p];
}
}
}
last = np;
}
void dfs(int u = 0){
f[u] = 1;
for(int i = 0; i < 26; i++){
if(!ch[u][i]) continue;
if(!f[ch[u][i]]) dfs(ch[u][i]);
f[u] += f[ch[u][i]];
}
}
LL query(){
dfs(); return f[0] - 1;
LL ret = 0; for(int i = 1; i <= tot; i++) ret += len[i] - len[link[i]]; return ret;
//return f[0] - 1;
}
}sam;
char s[MAXN];
void solve(){
int n; cin >> n;
cin >> s;
sam.init();
for(int i = 0, l = strlen(s); i < l; i++) sam.extend(s[i]-'a');
cout << sam.query() << endl;
}
int main(){
solve();
return 0;
}
Luogu P2408 不同子串个数【SAM】的更多相关文章
- luogu P2408 不同子串个数
考虑反向操作,去计算有多少组相同的子串,对于一组大小为k的极大相同子串的集合,ans-=k-1. 为了避免重复计算,需要一种有效的,有顺序的记录方案. 比如说,对于每一个相同组,按其起始点所在的位置排 ...
- LUOGU P2408 不同子串个数(后缀数组)
传送门 解题思路 后缀数组求本质不同串的裸题.\(ans=\dfrac{n(n+1)}{2} -\sum height[i]\). 代码 #include<iostream> #inclu ...
- 【文文殿下】洛谷P2408 不同子串个数
题目链接https://www.luogu.org/problemnew/show/P2408 SAM裸题,大力求就行了 #include<cstdio> #include<cstr ...
- p2408 不同子串个数
传送门 分析 首先我们不难求出一共有多少子串 之后我们只需要减掉重复个数即可 于是我们对于每个后缀减去它跟它前一名的最长公共前缀即可 代码 #include<iostream> #incl ...
- [洛谷P2408]不同子串个数
题目大意:给你一个字符串,求其中本质不同的字串的个数 题解:同[洛谷P4070][SDOI2016]生成魔咒,只要最后再输出就行了 卡点:无 C++ Code: #include <cstdio ...
- 洛谷P2408 不同子串个数 后缀数组 + Height数组
## 题目描述: 给你一个长为 $N$ $(N<=10^5)$ 的字符串,求不同的子串的个数我们定义两个子串不同,当且仅当有这两个子串长度不一样 或者长度一样且有任意一位不一样.子串的定义:原字 ...
- HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)
Reincarnation Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- HDU4622 (查询一段字符串的不同子串个数,后缀自动机)
http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给出一个字符串和q次询问,每次询问[l,r]区间内不同子串的个数 分析: N<=2000. 我 ...
- HDU 3948 不同回文子串个数
集训队论文中有求不同子串个数的做法,就是扫一遍height数组,过程中根据height数组进行去重.对于本题也是雷同的,只是每一次不是根据与排名在上一位的LCP去重,而是与上一次统计对答案有贡献的后缀 ...
随机推荐
- Mac上最好用的软件集合,没有之一
前言 题主从 windows 系统换成 macOS 系统已经4年多了.对于没有用过 Mac 电脑的人来说,可能无法理解 Mac 好用在哪里.不过对于一个用过 Mac 的开发者来说,从 windows ...
- JavaFX之班级未交作业统计
前言 最近转移了系统平台,用上了Ubuntu1804版本系统,原来用C#写的Windows窗体软件也不能用了,而且自己在班级上每周都需要收作业,所以写了这个软件.这篇博客主要记录这个JavaFX应用的 ...
- 解压rpm文件
rpm2cpio zabbix-2.2.2-0.el6.zbx.src.rpm |cpio -div
- ps 2020 下载
一款极具实用价值的作图软件--ps,由于正版价格昂贵,所以这里分享破解版的资源.b话少说,下面是下载链接和安装步骤: 下载链接: 百度网盘链接:https://pan.baidu.com/s/1XPf ...
- k8s集群中遇到etcd集群故障的排查思路
一次在k8s集群中创建实例发现etcd集群状态出现连接失败状况,导致创建实例失败.于是排查了一下原因. 问题来源 下面是etcd集群健康状态: 1 2 3 4 5 6 7 8 9 10 11 [roo ...
- VKM5对应的BAPI或者函数
在业务上,当一个交货单创建后,可能需要使用事物VKM5进行批准(解冻)才能做后续的捡配,发货过账等操作,通过搜索引擎发现,很多人也都会问是否有对应的bapi或者函数,替代VKM5,能够自开发程序进行批 ...
- Description Resource Path Location Type Failure to transfer org.apache.maven.plugins:maven-surefire-
url:https://www.pianshen.com/article/8003307916/ Description Resource Path Location Type Failure to ...
- Pku1236 Network of Schools
题目描述 n个学校构成一个有向图,通过m条边连接,一:问至少向图中多少个学校投放软件,可以使得所有学校直接或者间接的通过边(假设存在边(u,v),则向u投放v可以得到,而向v投放u不能通过v直接得到) ...
- Ubuntu对接GlusterFS
存储节点部署示例环境,仅供参考 主机名 IP 系统 gfs01 10.10.10.13 Ubuntu 16.04.3 LTS gfs02 10.10.10.14 Ubuntu 16.04.3 LTS ...
- 树莓派做私有云盘-极简版(owncloud)
这里直接给出配置好私有云的镜像,只需烧录镜像后微改配置后即可使用 链接:https://pan.baidu.com/s/1EOQaSQso-0wmnuWgZKknZg提取码:q26h 1.直接将此镜像 ...