博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spoj705 后缀数组求不同子串的个数
阅读量:4949 次
发布时间:2019-06-11

本文共 2292 字,大约阅读时间需要 7 分钟。

  题目链接

SUBST1 - New Distinct Substrings

no tags 

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 <= 50000

Output

For each test case output one number saying the number of distinct substrings.

Example

Input:
2
CCCCC
ABABA
Output:
5
9
题意:
求不同的子串的个数。
思路:
每一个子串都是某一个后缀的前缀。所以对于当前的后缀,他能够贡献的个数就是他的长度减去
rank[i]-1的那个的公共前缀长度。
 
/* * Author:  sweat123 * Created Time:  2016/6/29 13:46:26 * File Name: main.cpp */#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INF 1<<30#define MOD 1000000007#define ll long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define pi acos(-1.0)using namespace std;const int MAXN = 50010;char s[MAXN];int wa[MAXN],wb[MAXN],wc[MAXN],n,height[MAXN],r[MAXN],Rank[MAXN],sa[MAXN];void da(int *r,int *sa,int n,int m){ int *x = wa,*y = wb; for(int i = 0; i < m; i++)wc[i] = 0; for(int i = 0; i < n; i++)wc[x[i] = r[i]] ++; for(int i = 0; i < m; i++)wc[i] += wc[i-1]; for(int i = n - 1; i >= 0; i--)sa[--wc[x[i]]] = i; for(int p = 1,k = 1; p < n; m = p,k <<= 1){ p = 0; for(int i = n - k; i < n; i++)y[p++] = i; for(int i = 0; i < n; i++)if(sa[i] >= k)y[p++] = sa[i] - k; for(int i = 0; i < m; i++)wc[i] = 0; for(int i = 0; i < n; i++)wc[x[y[i]]] ++; for(int i = 0; i < m; i++)wc[i] += wc[i-1]; for(int i = n - 1; i >= 0; i--)sa[--wc[x[y[i]]]] = y[i]; swap(x,y); p = 1; x[sa[0]] = 0; for(int i = 1; i < n; i++){ x[sa[i]] = (y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k])?p-1:p++; } } }void calheight(int *r,int *sa,int n){ for(int i = 1; i <= n; i++)Rank[sa[i]] = i; int j,k; k = 0; for(int i = 0; i < n; height[Rank[i++]] = k){ for(k?k--:0,j = sa[Rank[i]-1]; r[j+k] == r[i+k]; k++); } }void solve(){ int ans = 0; for(int i = 1; i <= n; i++){ int tp = height[i]; int len = n - sa[i]; ans += len - tp; } printf("%d\n",ans);}int main(){ int t; scanf("%d",&t); while(t--){ scanf("%s",s); n = strlen(s); for(int i = 0; i < n; i++){ r[i] = s[i]; } r[n] = 0; da(r,sa,n+1,128); calheight(r,sa,n); solve(); } return 0;}

 

转载于:https://www.cnblogs.com/sweat123/p/5627008.html

你可能感兴趣的文章
文字过长 用 ... 表示 CSS实现单行、多行文本溢出显示省略号
查看>>
1Caesar加密
查看>>
【TP SRM 703 div2 500】 GCDGraph
查看>>
MapReduce 重要组件——Recordreader组件 [转]
查看>>
webdriver api
查看>>
转载-FileZilla Server源码分析(1)
查看>>
apache 实现图标缓存客户端
查看>>
MediaWiki左侧导航栏通过特殊页面就可以设置。
查看>>
html基础之DOM操作
查看>>
几种图表库
查看>>
揭秘:黑客必备的Kali Linux是什么,有哪些弊端?
查看>>
linux系统的远程控制方法——学神IT教育
查看>>
springboot+mybatis报错Invalid bound statement (not found)
查看>>
Linux环境下SolrCloud集群环境搭建关键步骤
查看>>
P3565 [POI2014]HOT-Hotels
查看>>
UVa11078:Open Credit System
查看>>
MongoDB的简单使用
查看>>
git clone 遇到的问题
查看>>
hdfs 命令使用
查看>>
hdu 1709 The Balance
查看>>