当前位置: 代码迷 >> 综合 >> SPOJ DISUBSTR Distinct Substrings(后缀数组)
  详细解决方案

SPOJ DISUBSTR Distinct Substrings(后缀数组)

热度:11   发布时间:2023-12-17 03:39:25.0

题意:

一个字符串有多少个不同的字串

思路:

一个字符串共有 n?(n+1)2 个,减去所有的height数组的值,就是减去了所有重复的子串

错误及反思:

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1010;
char arr[N];
int sa[N],rak[N],height[N];
void construct(const char *s,int n,int m) {static int t1[N],t2[N],c[N];int *x = t1,*y = t2;int i,j,k,p,l;memset(c,0,sizeof(c));for (i = 0; i < n; ++ i) c[x[i] = s[i]] ++;for (i = 1; i < m; ++ i) c[i] += c[i - 1];for (i = n - 1; i >= 0; -- i) sa[--c[x[i]]] = i;for (k = 1; k <= n; k <<= 1) {p = 0;for (i = n - k; i < n; ++ i) y[p++] = i;for (i = 0; i < n; ++ i) if (sa[i] >= k) y[p++] = sa[i] - k;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];std::swap(x,y);p = 1; x[sa[0]] = 0;for (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 ++;if (p >= n) break;m = p;}for (i = 0; i < n; ++ i) rak[sa[i]] = i;for (i = 0,l = 0; i < n; ++ i) {if (rak[i]) {j = sa[rak[i] - 1];while (s[i + l] == s[j + l]) l++;height[rak[i]] = l;if (l) l--;}}
}int main()
{int t;scanf("%d",&t);while(t--){scanf("%s",arr);int len=strlen(arr);construct(arr,len+1,128);int ans=len*(len+1)/2;for(int i=2;i<=len;i++){ans-=height[i];}printf("%d\n",ans);}
}
  相关解决方案