题目分析
题意即求有多少对字符串只相差一个字符,枚举删除每个字符后的哈希, 看有多少相等即可。
比如有如下字符串:$Sd123$,其中S部分的哈希值为H,删除的是d,则原字符串的哈希值为$$(((H * T + d) * T + 1) * T + 2) * T + 3 = H * T^4 + d * T^3 + 1 * T^2 + 2 * T + 3$$
删除过后就为$$((H * T + 1) * T + 2) * T +3 = H * T^3 + 1 * T^2 + 2 * T + 3$$
也就是将1以前的哈希值全部剪去然后加上d之前的哈希值乘以$T^{len - delpos}$。
code
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N = 3e4 + 5, L = 205, Mod = 23333; typedef unsigned long long ull; const ull H = 149; ull hash[N][L], poww[L], go[N << 2], t[N]; int ecnt, adj[Mod + 5], nxt[N << 2]; int n, l, m, cnt; char s[N][L]; inline ull del(int k, int d){ return hash[k][l] - hash[k][d] * poww[l - d] + hash[k][d - 1] * poww[l - d]; } int main(){ scanf("%d%d%d", &n, &l, &m); for(int i = 1; i <= n; i++) scanf("%s", s[i] + 1); for(int i = 1; i <= n; i++) for(int j = 1; j <= l; j++) hash[i][j] = hash[i][j - 1] * H + s[i][j]; poww[0] = 1; for(int i = 1; i <= L; i++) poww[i] = poww[i - 1] * H; for(int j = 1; j <= l; j++){ for(int i = 1; i <= n; i++) t[i] = del(i, j); sort(t + 1,t + n + 1); int sum = 1; for(int i = 2; i <= n; i++){ if(t[i] == t[i - 1]){ cnt += sum; sum++; } else sum = 1; } } printf("%d", cnt); return 0; }
时间: 2024-10-05 06:30:06