您的位置:首页 > 其它

SPOJ 705 New Distinct Substrings 后缀数组

2016-02-15 11:20 363 查看
LINK: http://www.spoj.com/problems/SUBST1/

bzoj 3230做着做着就滚来做这题了。。

求一个字符串的不等(?)子串个数。

比如字符串ababa,其排好序的后缀是:

a
aba
ababa
ba
baba


然后每个后缀可以产生以其长度n−sai+1为个数的子串,但和有序上一个后缀会产生重复子串,个数为与其的公共前缀长度,因此答案为

∑n−sai+1−heighti

其中sa和height都从1开始。

不过下面的程序是从0开始的。。

这程序其实就是bzoj3230稍微改了下。。

奇怪了怎么改都是0.02s

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define rep(i,j,k) for(int i=j;i<k;i++)
#define FOR(i,j,k) for(int i=j;i<=k;i++)
const int N = 50100;
typedef long long ll;

ll read() {
ll s = 0, f = 1; char ch = getchar();
for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = -1;
for (; '0' <= ch && ch <= '9'; ch = getchar()) s = s * 10 + ch - '0';
return s * f;
}

char str
;
struct SuffixArray {
char r
;
int n, m, num
, z
;
int sa
, rk
, h
;
int wa
, wb
, wv
, c
;
ll s
;

private: SuffixArray(){}
public: SuffixArray(char *_r, int _n, int _m) {
rep(i,0,_n) r[i]=_r[i]; r[_n] = 0;
n = _n + 1; m = _m;
da(); calHeight(); init();
}

void *operator new(size_t) {
static SuffixArray r;
return &r;
}

void sort(int *sa, int *x, int *y, int n, int m) {
rep(i,0,m) c[i] = 0;
rep(i,0,n) c[x[i]]++;
rep(i,1,m) c[i] += c[i-1];
for(int i=n-1;i>=0;i--) sa[--c[x[i]]] = y[i];
}

void da() {
int j, p, *x = wa, *y = wb, *t;
rep(i,0,n) x[i]=r[i],z[i]=i;
sort(sa, x, z, n, m);
for(j=1,p=1;p<n;j*=2,m=p) {
p=0;
rep(i,n-j,n) y[p++] = i;
rep(i,0,n) if(sa[i]>=j) y[p++]=sa[i]-j;
rep(i,0,n) wv[i]=x[y[i]];
sort(sa, wv, y, n, m);
swap(x,y);p=1;x[sa[0]]=0;
rep(i,1,n) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++;
}
}

void calHeight() {
int k = 0;
rep(i,0,n) rk[sa[i]] = i;
rep(i,0,n-1) {
if(k)k--;
for(int j=sa[rk[i]-1];r[i+k]==r[j+k];k++);
h[rk[i]]=k;
}
rep(i,1,n) s[i] = s[i - 1] + (n - 1 - sa[i]) - h[i];
}
};

int main() {
int n, m, l, r, id; ll ans = 0, t, l1, r1, l2, r2;
SuffixArray *sa;
log[0] = -1; rep(i,1,N) log[i] = log[i / 2] + 1;
n = read();
while (n--) {
scanf("%s", str);
m = strlen(str);
sa = new SuffixArray(str, m, 255);
printf("%d\n", sa->s[m]);
}
return 0;
}


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

Output

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

Example

Input:

2

CCCCC

ABABA

Output:

5

9
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: