SPOJ(后缀数组求不同子串个数)
DISUBSTR - Distinct Substrings
Given a string, we need to find the total number of its distinct substrings.
Input
T- number of test cases. T<=20;
Each test case consists of one string, whose length is <= 1000
Output
For each test case output one number saying the number of distinct substrings.
Example
Sample Input:
2
CCCCC
ABABA
Sample Output:
5
9
Explanation for the testcase with string ABABA:
len=1 : A,B
len=2 : AB,BA
len=3 : ABA,BAB
len=4 : ABAB,BABA
len=5 : ABABA
Thus, total number of distinct substrings is 9.
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=;
char buf[MAXN];
int sa[MAXN];
int rnk[MAXN];
int tmp[MAXN];
int lcp[MAXN];
int len,k; bool comp(int i,int j)
{
if(rnk[i]!=rnk[j]) return rnk[i]<rnk[j];
else{
int ri=(i+k<=len)?rnk[i+k]:-;
int rj=(j+k<=len)?rnk[j+k]:-;
return ri<rj;
}
} void getsa()
{
memset(rnk,,sizeof(rnk));
memset(sa,,sizeof(sa));
memset(tmp,,sizeof(tmp)); len=strlen(buf);
for(int i=;i<len;i++)
{
sa[i]=i;
rnk[i]=buf[i]-'A';
}
sa[len]=len;
rnk[len]=-; for(k=;k<=len;k*=)
{
sort(sa,sa+len+,comp); tmp[sa[]]=;
for(int i=;i<=len;i++)
{
tmp[sa[i]]=tmp[sa[i-]]+(comp(sa[i-],sa[i])?:);
} for(int i=;i<=len;i++)
{
rnk[i]=tmp[i];
}
}
} void getlcp()
{
memset(rnk,,sizeof(rnk));
memset(lcp,,sizeof(lcp));
getsa();
for(int i=;i<=len;i++)
{
rnk[sa[i]]=i;
} int h=;
lcp[]=h;
for(int i=;i<len;i++)
{
int j=sa[rnk[i]-];
if(h>) h--;
for(;h+i<len&&h+j<len;h++)
if(buf[i+h]!=buf[j+h]) break;
lcp[rnk[i]-]=h;
}
} void debug()
{
for(int i=;i<=len;i++)
{
int l=sa[i];
if(l==len)
{
printf("%d %d\n",l,lcp[i]);
}
else
{
for(int j=l;j<len;j++)
printf("%c ",buf[j]);
printf("%d\n",lcp[i]);
}
} }
int T;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%s",buf);
int res=;
getlcp();
res+=(len+)*len/;
for(int i=;i<=len;i++)
res-=lcp[i];
printf("%d\n",res);
} return ;
}
SPOJ(后缀数组求不同子串个数)的更多相关文章
- SPOJ Distinct Substrings(后缀数组求不同子串个数,好题)
DISUBSTR - Distinct Substrings no tags Given a string, we need to find the total number of its dist ...
- [spoj DISUBSTR]后缀数组统计不同子串个数
题目链接:https://vjudge.net/contest/70655#problem/C 后缀数组的又一神奇应用.不同子串的个数,实际上就是所有后缀的不同前缀的个数. 考虑所有的后缀按照rank ...
- SPOJ SUBST1 New Distinct Substrings(后缀数组 本质不同子串个数)题解
题意: 问给定串有多少本质不同的子串? 思路: 子串必是某一后缀的前缀,假如是某一后缀\(sa[k]\),那么会有\(n - sa[k] + 1\)个前缀,但是其中有\(height[k]\)个和上一 ...
- spoj 694. Distinct Substrings 后缀数组求不同子串的个数
题目链接:http://www.spoj.com/problems/DISUBSTR/ 思路: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数.如果所有的后缀按照su ...
- spoj705 后缀数组求不同子串的个数
http://www.spoj.com/problems/SUBST1/en/ 题目链接 SUBST1 - New Distinct Substrings no tags Given a stri ...
- poj 1743 男人八题之后缀数组求最长不可重叠最长重复子串
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 14874 Accepted: 5118 De ...
- 【POJ2774】Long Long Message(后缀数组求Height数组)
点此看题面 大致题意: 求两个字符串中最长公共子串的长度. 关于后缀数组 关于\(Height\)数组的概念以及如何用后缀数组求\(Height\)数组详见这篇博客:后缀数组入门(二)--Height ...
- poj 1743 后缀数组 求最长不重叠重复子串
题意:有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题. “主题”是整个音符序列的一个子串,它需要满足如下条件:1 ...
- SPOJ REPEATS Repeats (后缀数组 + RMQ:子串的最大循环节)题解
题意: 给定一个串\(s\),\(s\)必有一个最大循环节的连续子串\(ss\),问最大循环次数是多少 思路: 我们可以知道,如果一个长度为\(L\)的子串连续出现了两次及以上,那么必然会存在\(s[ ...
随机推荐
- AngularJS的ng-repeat显示属性名和属性值
代码下载:https://files.cnblogs.com/files/xiandedanteng/AngularJSAuthorRepeat.rar 代码: <!DOCTYPE HTML P ...
- vue2.0 vue-router
一.SPA中路由的简单实现 main.js import Vue from 'vue' import App from './App' import VueRouter from 'vue-route ...
- mysql查询处理顺序
http://zhangzhaoaaa.iteye.com/blog/1689412参考:<MYSQL技术内幕SQL编程> select distinct <selectlist&g ...
- mysql truncate table命令使用总结
truncate使用注意 由于上过truncate table a_table命令一次当,将教训记录下来,以示警戒! mysql truncate table a_table命令受影响结果说明 ...
- PJSIP 调用的GUID库
PJSIP库产生随机序列串用到GUID库,针对不同的平台使用的方式不同:Windows平台下使用的是Windows系统API CoCreateGuid,在方法 pj_generate_unique_s ...
- iOS 获取图片某一点的颜色对象(UIColor*)。
- (UIColor *)colorAtPixel:(CGPoint)point { // Cancel if point is outside image coordinates if (!CGRe ...
- AQS实现公平锁和非公平锁
https://www.cnblogs.com/chengdabelief/p/7493200.html AQS(AbstractQueuedSynchronizer类)是一个用来构建锁和同步器的框架 ...
- MacOS 修改主机名
修改主机名 sudo scutil --set HostName xxx 修改共享名 sudo scutil --set ComputerName xxx
- 当CSDN携手Markdown
当CSDN携手Markdown Tags: CSDN Markdown 当CSDN携手Markdown Markdown CSDN-Markdown 也不知道是不是基于 Github 崛起的因素,Ma ...
- mac下执行文件出现Permission Denied的解决
mac 下终端访问文件出现“Permission Denied”解决方案: 一个文件有3种权限,读.写.可执行,你这个文件没有可执行权限,需要加上可执行权限. 1. 终端下先 cd到该文件的目录下 2 ...