洛谷P2408 不同字串个数 [后缀数组]
不同字串个数
题目背景
因为NOI被虐傻了,蒟蒻的YJQ准备来学习一下字符串,于是它碰到了这样一道题:
题目描述
给你一个长为N的字符串,求不同的子串的个数
我们定义两个子串不同,当且仅当有这两个子串长度不一样 或者长度一样且有任意一位不一样。
子串的定义:原字符串中连续的一段字符组成的字符串
输入输出格式
输入格式:
第一行一个整数N
接下来一行N个字符表示给出的字符串
输出格式:
一行一个整数,表示不一样的子串个数
输入输出样例
5
aabaa
11
3
aba
5
说明
请使用64位整数来进行输出
(具体来说,C++和C选手请使用long long 类型,pascal选手请使用Int64)
由于输入文件过大,请使用 高效的读入方法(具体的,c++和c选手请不要使用cin,pascal选手不需要管)
对于30%的数据, $N\le 1000$
对于100%的数据, $N\le 10^5$
分析:
后缀数组入门好题,刚学,特地来水一波。
首先做这道题需要会后缀数组,并深入理解$height[]$数组的含义,然后需要知道一个非常重要的性质。下面这一段话引用自罗穗骞的论文:
每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数。如果所有的后缀按照 suffix(sa[1]), suffix(sa[2]),suffix(sa[3]), …… ,suffix(sa[n])的顺序计算,不难发现,对于每一次新加进来的后缀 suffix(sa[k]),它将产生 n-sa[k]+1 个新的前缀。但是其中有height[k]个是和前面的字符串的前缀是相同的。所以 suffix(sa[k])将“贡献”出 n-sa[k]+1- height[k]个不同的子串。累加后便是原问题的答案。这个做法的时间复杂度为 O(n)。
知道这些这道题就可以轻松A过了。
Code:
//It is made by HolseLee on 13th Aug 2018
//Luogu.org P2408
#include<bits/stdc++.h>
using namespace std; typedef long long ll;
const int N=1e5+;
int n,m,height[N],sa[N],rk[N],y[N],c[N];
ll ans;
char s[N]; void Sort()
{
for(int i=;i<=m;++i)c[i]=;
for(int i=;i<=n;++i)c[rk[i]]++;
for(int i=;i<=m;++i)c[i]+=c[i-];
for(int i=n;i>=;--i)sa[c[rk[y[i]]]--]=y[i];
} void getsa()
{
for(int i=;i<=n;++i)rk[i]=s[i]-'',y[i]=i;
Sort();
for(int k=,cnt=;cnt<n;m=cnt,k<<=){
cnt=;
for(int i=;i<=k;++i)y[++cnt]=n-k+i;
for(int i=;i<=n;++i)if(sa[i]>k)y[++cnt]=sa[i]-k;
Sort();
swap(y,rk);
rk[sa[]]=cnt=;
for(int i=;i<=n;++i)
rk[sa[i]]=(y[sa[i]]==y[sa[i-]]&&y[sa[i]+k]==y[sa[i-]+k])?cnt:++cnt;
}
} void getheight()
{
int k=,j;
for(int i=;i<=n;++i){
if(k)k--;
j=sa[rk[i]-];
while(s[i+k]==s[j+k])k++;
height[i]=k;
}
} int main()
{
scanf("%d%s",&n,s+);
m=;
getsa();getheight();
for(int i=;i<=n;++i)
ans+=(n-sa[i]+-height[i]);
printf("%lld",ans);
return ;
}
洛谷P2408 不同字串个数 [后缀数组]的更多相关文章
- 洛谷2408不同字串个数/SPOJ 694/705 (后缀数组SA)
真是一个三倍经验好题啊. 我们来观察这个题目,首先如果直接整体计算,怕是不太好计算. 首先,我们可以将每个子串都看成一个后缀的的前缀.那我们就可以考虑一个一个后缀来计算了. 为了方便起见,我们选择按照 ...
- 【题解】洛谷P1032 [NOIP2002TG]字串变换(BFS+字符串)
洛谷P1032:https://www.luogu.org/problemnew/show/P1032 思路 初看题目觉得挺简单的一道题 但是仔细想了一下发现实现代码挺麻烦的 而且2002年的毒瘤输入 ...
- 【洛谷】P1032 字串变换
题目地址:https://www.luogu.org/problemnew/show/P1032 洛谷训练场BFS的训练题呀. “BFS不就是用队列的思想去遍历一切情况嘛.我已经不是小孩子了,我肯定能 ...
- 洛谷 P1032 【字串变换】
感觉这个题用一些常用的stl和string函数会非常简单..(难道就是考这两个的吗? vector<pair<string,string>>pos//用于变化 map<s ...
- 洛谷P2178 [NOI2015]品酒大会 后缀数组+单调栈
P2178 [NOI2015]品酒大会 题目链接 https://www.luogu.org/problemnew/show/P2178 题目描述 一年一度的"幻影阁夏日品酒大会" ...
- 洛谷P4493 [HAOI2018]字串覆盖(后缀自动机+线段树+倍增)
题面 传送门 题解 字符串就硬是要和数据结构结合在一起么--\(loj\)上\(rk1\)好像码了\(10k\)的样子-- 我们设\(L=r-l+1\) 首先可以发现对于\(T\)串一定是从左到右,能 ...
- 【洛谷 P2408】 不同子串个数(后缀自动机)
题目链接 裸体就是身体. 建出\(SAM\),\(DAG\)上跑\(DP\),\(f[u]=1+\sum_{(u,v)\in DAG}f[v]\) 答案为\(f[1]-1\)(因为根节点没有字符) # ...
- 【洛谷P3411】字串变换
题解:普通的 BFS 没什么可说的,字符串处理是这道题的难点,同时需要注意哈希判重. 另外,对于 \(string\) 类来说,学到了一个 push_back((char)) 操作. c++strin ...
- [洛谷P1279][题解]字串距离
题目戳我 很明显的这题是一道dp,主要讲一下几个细节 1.初始化 我们需要初始化边界情况也就是一个字符串为空的情况 #----------# #----------# A:aaaaaa A:□□□□□ ...
随机推荐
- 在服务器上运行Jar包
在服务器上运行Jar包 并且该Jar包依赖其他的Jar文件的时候,采用如下格式 java -Djava.ext.dirs=你依赖的Jar文件路径 -jar 你要运行的Jar文件 包名+类名 例如: j ...
- Xamarin Error:Could not find android.jar for API Level 23.
背景:打开别人Xamarin项目找不到android.jar文件 报错: 解决方案1:工具——Android——Amdroid SDK 管理器…出现以下窗口(根据需要的[API级别])勾选相应的Pla ...
- Python学习笔记(2.1)函数参数练习
关键字参数 和 命名关键字参数 # -*- coding: utf-8 -*- def print_scores(**kw): print(' Name Score') print('-------- ...
- C11线程管理:异步操作
1.异步操作 C++11提供了异步操作相关的类,std::future.std::promise和std::package_task.std::future作为异步结果的传输通道,方便的获取线程函数的 ...
- C11线程管理:条件变量
1.简介 C11提供另外一种用于等待的同步机制,它可以阻塞一个或者多个线程,直到收到另外一个线程发出的通知或者超时,才会唤醒当前阻塞的线程.条件变量要和互斥量配合起来使用. condition_var ...
- Unicode/UTF-8/GBK/ASCII 编码简介
转载:http://blog.csdn.net/u014785687/article/details/73928167 一.字符编码简介 1.ASCII编码 每一个ASCII码与一个8位(bit)二进 ...
- Flask---使用Bootstrap新建第一个demo
Flask---使用Bootstrap新建第一个demo 参考自http://www.jianshu.com/p/417bcbad82fb 还有<Flask web开发> 前端用到Boot ...
- 常用Path路径
正三角形(左):<Path Data="M40,0 L0,30 40,60 z" Stretch="Uniform"/> 正三角形(上):<P ...
- Oracle Number类型超长小数位为0问题
碰到了一个非常奇怪的问题,从Excel拷贝出来的数据,位数很长,通过Pl Sql 导出到Oracle后为0了,而且设置查询条件为0时,无法查询出来,条件大于0居然能查询出来,通过to_number也是 ...
- sublime出现卡顿的现象
这几天,用sublime总是写一个代码就卡顿,卡卡卡,,,,要死的~ 最后,才发现是因为安装了一个插件:GitGutter插件,所以,小伙伴们请跟上我的节奏~~~~~ (1)Ctrl + Shift ...