涉及知识点:
solution:
- (本题将每一个字符串的每一个子串的哈希值扔到map里)
- (因为本题的字符串长度小,所以也可以直接存子串)
- (注意本题每个字符串如果有重复的子串,只取一个,这里是用set去重)
- (然后看每个字符串对应的键值为多少相加即可(注意要减去它自己))
- (本题由于字符串数目过多,且不用排序,最好使用unordered_map)
std:
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int P = 131;
char str[15];
ull h[15],p[15];
ull sub[20010];
unordered_map<ull,int> mp;
set<ull> se;
ull get(int l,int r)
{
return h[r] - h[l-1] * p[r-l+1];
}
int main()
{
int n;
scanf("%d",&n);
p[0]=1;
for (int t = 1 ; t <= n ; t ++ )
{
se.clear();
scanf("%s",str+1);
int len = strlen(str+1);
for (int i = 1 ; i <= len; i ++ )
{
if(!p[i]) p[i] = p[i-1] * P;
h[i] = h[i-1]*P + (str[i]-'a'+1);
}
sub[t] = h[len];
for (int l = 1 ; l <= len ; l ++ )
{
for (int r = l ; r <= len; r ++ )
{
se.insert(get(l,r));
}
}
for (set<ull>::iterator it = se.begin() ; it != se.end() ; it ++ )
{
mp[*it] ++ ;
}
}
ull ans = 0;
for (int i = 1 ; i <= n ; i ++ )
{
auto it = mp.find(sub[i]);
if(it == mp.end()) continue;
else ans += it->second-1;
}
printf("%lld
",ans);
return 0;
}