http://www.spoj.com/problems/DISUBSTR/

题意:求字符串不同子串的数目。

#include <bits/stdc++.h>
using namespace std; const int N=1005;
void sort(int *x, int *y, int *sa, int n, int m) {
static int c[N], i;
for(i=0; i<m; ++i) c[i]=0;
for(i=0; i<n; ++i) ++c[x[y[i]]];
for(i=1; i<m; ++i) c[i]+=c[i-1];
for(i=n-1; i>=0; --i) sa[--c[x[y[i]]]]=y[i];
}
void hz(int *a, int *sa, int n, int m) {
static int t1[N], t2[N], i, j, p, *x, *y, *t;
x=t1, y=t2;
for(i=0; i<n; ++i) x[i]=a[i], y[i]=i;
sort(x, y, sa, n, m);
for(j=1, p=1; p<n; j<<=1, m=p) {
p=0;
for(i=n-j; i<n; ++i) y[p++]=i;
for(i=0; i<n; ++i) if(sa[i]-j>=0) y[p++]=sa[i]-j;
sort(x, y, sa, n, m);
for(t=x, x=y, y=t, p=1, x[sa[0]]=0, i=1; i<n; ++i)
x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+j]==y[sa[i-1]+j]?p-1:p++;
}
}
void geth(int *s, int *sa, int *h, int n) {
static int rank[N], j, i, k;
for(i=1; i<=n; ++i) rank[sa[i]]=i;
for(k=0, i=1; i<=n; h[rank[i++]]=k)
for(k?--k:0, j=sa[rank[i]-1]; s[i+k]==s[j+k]; ++k);
} int a[N], sa[N], h[N], n;
char s[N];
int main() {
int cs;
scanf("%d", &cs);
while(cs--) {
scanf("%s", s+1);
n=strlen(s+1);
for(int i=1; i<=n; ++i) a[i]=s[i];
hz(a, sa, n+1, 128);
geth(a, sa, h, n);
int ans=0;
for(int i=1; i<=n; ++i) ans+=n-sa[i]+1-h[i];
printf("%d\n", ans);
}
return 0;
}

  


经典题....首先每个后缀的前缀就是一个子串,因此每个后缀可以构成这个后缀长度大小那么多个子串。但是我们要考虑重合的情况,即我们剪掉与上一个后缀子串相同前缀的height值就好啦

【SPOJ】694. Distinct Substrings的更多相关文章

  1. 【SPOJ】Distinct Substrings(后缀自动机)

    [SPOJ]Distinct Substrings(后缀自动机) 题面 Vjudge 题意:求一个串的不同子串的数量 题解 对于这个串构建后缀自动机之后 我们知道每个串出现的次数就是\(right/e ...

  2. 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)

    [SPOJ]Distinct Substrings/New Distinct Substrings(后缀数组) 题面 Vjudge1 Vjudge2 题解 要求的是串的不同的子串个数 两道一模一样的题 ...

  3. 【SPOJ】Distinct Substrings

    [SPOJ]Distinct Substrings 求不同子串数量 统计每个点有效的字符串数量(第一次出现的) \(\sum\limits_{now=1}^{nod}now.longest-paren ...

  4. SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转

    694. Distinct Substrings Problem code: DISUBSTR   Given a string, we need to find the total number o ...

  5. 【SPOJ】Substrings(后缀自动机)

    [SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...

  6. 【SPOJ】NUMOFPAL - Number of Palindromes(Manacher,回文树)

    [SPOJ]NUMOFPAL - Number of Palindromes(Manacher,回文树) 题面 洛谷 求一个串中包含几个回文串 题解 Manacher傻逼题 只是用回文树写写而已.. ...

  7. 【SPOJ】Longest Common Substring II (后缀自动机)

    [SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...

  8. 【SPOJ】Longest Common Substring(后缀自动机)

    [SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...

  9. 【SPOJ】Power Modulo Inverted(拓展BSGS)

    [SPOJ]Power Modulo Inverted(拓展BSGS) 题面 洛谷 求最小的\(y\) 满足 \[k\equiv x^y(mod\ z)\] 题解 拓展\(BSGS\)模板题 #inc ...

随机推荐

  1. 【OpenStack】OpenStack系列16之OpenStack镜像制作

    参考 参考: https://www.google.com.hk/?gws_rd=ssl#safe=strict&q=openstack+img+%E5%88%B6%E4%BD%9C http ...

  2. Java单链表、双端链表、有序链表实现

    单链表: insertFirst:在表头插入一个新的链接点,时间复杂度为O(1) deleteFirst:删除表头的链接点,时间复杂度为O(1) 有了这两个方法,就可以用单链表来实现一个栈了,见htt ...

  3. Merge Two Sorted Arrays

    Merge two given sorted integer array A and B into a new sorted integer array. Example A=[1,2,3,4] B= ...

  4. DP:Apple Catching(POJ 2385)

    牛如何吃苹果 问题大意:一个叫Bessie的牛,可以吃苹果,然后有两棵树,树上苹果每分钟会掉一个,这只牛一分钟可以在两棵树中往返吃苹果(且不吃地上的),然后折返只能是有限次W,问你这只叫Bessie的 ...

  5. [Android Pro] 监听WIFI 打开广播

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-perm ...

  6. [Git] Git 文件归档, include submodule

      git archive命令,可以对任意提交对应的目录树建立归档. $ git archive -o latest.zip HEAD  基于最新提交建立归档文件latest.zip $ git ar ...

  7. solr6.0学习

    solr6.0学习(一)环境搭建准备工作:目前最新版本6.0.下载solr 6.0:Solr6.0下载JDK8 下载jdk1.8:jdk1.8[solr6.0是基于jdk8开发的]tomcat8.0 ...

  8. mysql 指定端口

    mysql -P3307 -uemove -h180. -p #-P是指定端口

  9. LINUX下安装TeamViewer

    https://www.teamviewer.com/zhcn/download/linux/ [root@ok teamviewer]# yum install -y teamviewer_11.0 ...

  10. Webservice加上SoapHeader验证方式

    提供一种基于SoapHeader的自定义验证方式,代码如下: public class MySoapHeader : System.Web.Services.Protocols.SoapHeader ...