SPOJ-SUBST1 New Distinct Substrings (求不同子串数量)(后缀数组模板)
New Distinct Substrings
问题描述
给定一个字符串,我们需要找到它的不同子字符串的总数。
输入
T-测试用例的数量。T < = 20;每个测试用例由一个字符串组成,其长度<= 50000
输出
对于每个测试用例,输出一个数字,表示不同子字符串的数量。
Input:
2
CCCCC
ABABA
Output:
5
9
分析:
假设串长度为n
所有子串个数就是n*(n+1)/2
重复个数就是height,遍历haight减去就行了
顺便留模板
code:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#define ll long long
using namespace std;
const int maxm=5e4+5;
char s[maxm];
int t1[maxm],t2[maxm],c[maxm];
int rk[maxm],sa[maxm],height[maxm];
bool cmp(int *r,int a,int b,int l){return r[a]==r[b]&&r[a+l]==r[b+l];
}
void getsa(int n,int m){int *x=t1,*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 num=0;for(int i=n-k;i<n;i++)y[num++]=i;for(int i=0;i<n;i++)if(sa[i]>=k)y[num++]=sa[i]-k;for(int i=0;i<m;i++)c[i]=0;for(int i=0;i<n;i++)c[x[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);x[sa[0]]=0;num=1;for(int i=1;i<n;i++){x[sa[i]]=cmp(y,sa[i],sa[i-1],k)?num-1:num++;}if(num>=n)break;m=num;}
}
void geth(int n){int k=0;for(int i=1;i<=n;i++)rk[sa[i]]=i;for(int i=0;i<n;i++){if(k)k--;int j=sa[rk[i]-1];while(i+k<n&&j+k<n&&s[i+k]==s[j+k])k++;height[rk[i]]=k;}
}
void solve(int n){int ans=(ll)n*(n+1)/2;for(int i=2;i<=n;i++){//height只有2-n有用ans-=height[i];}printf("%d\n",ans);
}
int main(){int T;scanf("%d",&T);while(T--){scanf("%s",s);int n=strlen(s),m=130;getsa(n+1,m);//求sa的时候把末尾的0也算进去geth(n);//求height的时候不用+1solve(n);}return 0;
}
SPOJ-SUBST1 New Distinct Substrings (求不同子串数量)(后缀数组模板)相关推荐
- 求两个字符串的LCS(最长公共子串)后缀数组
题意: 给两个字符串,求出它们的最长公共子串的长度. 比如 yeshowmuchiloveyoumydearmotherreallyicannotbelieveit yeaphowmuchilovey ...
- BZOJ3230 相似子串 【后缀数组】
题目链接 BZOJ3230 权限题 题解 后缀数组基础题 询问第K大不同子串和正反lcp长度 如果您RE了,您就要知道询问的输入会爆LL #include<algorithm> #incl ...
- 【SPOJ 694】Distinct Substrings (更直接的求法)
[链接]h在这里写链接 [题意] 接上一篇文章 [题解] 一个字符串所有不同的子串的个数=∑(len-sa[i]-height[i]) [错的次数] 0 [反思] 在这了写反思 [代码] #inclu ...
- SPOJ-New Distinct Substrings,注意会爆int
SUBST1 - New Distinct Substrings 和上一题题意一样,只是数据范围有所改动,50000. 思路还是和上一题一样,所有字串数(len+1)*len/2.注意这里可能爆int ...
- SPOJ - PHRASES Relevant Phrases of Annihilation —— 后缀数组 出现于所有字符串中两次且不重叠的最长公共子串...
题目链接:https://vjudge.net/problem/SPOJ-PHRASES PHRASES - Relevant Phrases of Annihilation no tags You ...
- |spoj 694|后缀数组|Distinct Substrings
spoj 694 给出一个字符串,求字符串中不相同的子串个数. 我们可以知道,字符串中的每个子串都是某个后缀的前缀,于是题目转化为求不相同的后缀的前缀问题.对于每一个SA[k]SA[k]开始的后缀,将 ...
- New Distinct Substrings(后缀数组)
New Distinct Substrings(后缀数组) 给定一个字符串,求不相同的子串的个数.\(n<=50005\). 显然,任何一个子串一定是后缀上的前缀.先(按套路)把后缀排好序,对于 ...
- 后缀数组求最长重复子串
问题描述 给定一个字符串,求出其最长重复子串 例如:abcdabcd 最长重复子串是 abcd,最长重复子串可以重叠 例如:abcdabcda,这时最长重复子串是 abcda,中间的 a 是被重叠的. ...
- 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数
目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...
- 给定一个字符串,判断该字符串中是否包含某个子串.如果包含,求出子串的所有出现位置. 要求:从键盘输入两个字符串,第一个是给定的字符串,第二个是子串。
给定一个字符串,判断该字符串中是否包含某个子串.如果包含,求出子串的所有出现位置. 要求:从键盘输入两个字符串,第一个是给定的字符串,第二个是子串. 输入 abcd23abc34bcd bc 输出 1 ...
最新文章
- win10用什么软件测试硬件,Win10系统下硬件设备检测工具的使用方法
- 欧盟调查或拖累进程 高通收购NXP一波三折
- eCognition易康导出分割结果
- C语言基础-简单程序分析
- USB和USB2.0万能驱动
- Python文件的读取与写入
- java 复制标记_java-对于大文件,在标记inputStream并将其重置...
- java 单例加锁方法的讨论
- 【PHP+MySQL学习笔记】php操作MySQL数据库中语句
- asp.net中前台javascript与c#函数相互调方法
- Windows10电脑线 下hosts文件地址
- poj 1459 Power Network 多源多汇网络流
- Ajax的工具类AjaxUtils,使用struts返回Json类型
- 将RP文件导出为HTML文件
- eplan图纸怎么发给别人_如何保护你的EPLAN图纸
- 微信小程序实现输入车牌号码的功能(附效果图)
- 从0到1搭建大数据平台之数据采集篇
- 服务机器人分类包括哪些?
- 洛谷P4568飞行路线
- 360浏览器兼容模式下站点显示不正常,极速模式正常
热门文章
- RS232接口与电平
- Linux内存从0到1学习笔记(7.3,用户空间虚拟内存之内存映射)
- STM8L 低功耗模式说明
- 云服务器 微信支付开发,WeX5怎么样实现支付宝和微信支付接口
- EURA欧瑞E1000系列变频器使用PID实现恒压供水功能的相关参数设置及接线
- 我是如何做测试项目管理的
- 使用动软.net代码生成器生成数据库文档
- 分别使用docx4j,jacob将文字与图片插入word中书签位置
- YYText 源码剖析:CoreText 与异步绘制
- 克拉克变换(Clarke Transformation)