传送门:DISUBSTR
题意:给定一个字符串,求不同子串个数。
分析:由于数据较小,直接枚举长度为1,2...n的所有子串进行hash即可,复杂度(O(n^2)),后缀数组才是正解(O(nlogn)。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <cstdlib> #include <map> #define LL long long #define N 1000010 using namespace std; const int HASH=10007; const int MAXN=1010; struct HASHMAP { int head[HASH],next[MAXN],size; unsigned long long state[MAXN]; int f[MAXN]; void init() { size=0; memset(head,-1,sizeof(head)); } int insert(unsigned long long val) { int h=val%HASH; for(int i=head[h];~i;i=next[i]) { if(val==state[i]) { return 0; } } state[size]=val; next[size]=head[h]; head[h]=size++; return 1; } }H; const int SEED=13331; unsigned long long p[MAXN]; unsigned long long s[MAXN]; char str[MAXN]; int main() { p[0]=1; for(int i=1;i<MAXN;i++)p[i]=p[i-1]*SEED; int T; scanf("%d",&T); while(T--) { scanf("%s",str); int n=strlen(str); s[0]=0; for(int i=1;i<=n;i++) { s[i]=s[i-1]*SEED+str[i-1]; } int ans=0; for(int L=1;L<=n;L++) { H.init(); for(int i=1;i+L-1<=n;i++) { int res=H.insert(s[i+L-1]-s[i-1]*p[L]); ans+=res; } } printf("%d\n",ans); } }