本文主要是介绍SPOJ SUBST1 New Distinct Substrings(后缀数组),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题意:
一个字符串有多少个不同的字串
思路:
题意与思路和 SPOJ DISUBSTR完全相同,唯一不同是数据范围,用后缀数组复杂度完全够,注意下long long 即可
错误及反思:
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=50000+10;
int sa[N],rak[N],height[N];
char s[N];
void construct(const char *s,int n,int m = 256)
{static int t1[N],t2[N],c[N];int *x = t1,*y = t2;int i,j,k,p,l;for (i = 0; i < m; ++ i) c[i] = 0;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];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",s);int len=strlen(s);construct(s,len+1);long long sum=0;for(int i=2;i<=len;i++){sum+=1ll*height[i];}printf("%I64d\n",1ll*len*(len+1)/2-sum);}
}
这篇关于SPOJ SUBST1 New Distinct Substrings(后缀数组)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!