题解:AT_abc483_e [ABC483E] Typo Pairs
这篇文章中,题中的字母都变成了小写字母。
算法
本题需要求出有多少个
对于汉明距离小于等于
这里面将汉明距离小于等于
这个时候,汉明距离等于
成立,解得
时间复杂度是
代码
下面是时间复杂度是
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int n, m, num[26*26*26*26*26], tmp=1;
char s[(int)2e5][7];
long long ans, c;
int cmp(const void *a, const void *b) {return memcmp(a, b, m);}
int main() {
scanf("%d %d", &n, &m);
for(int i=0;i<n;++i) scanf("%s", s[i]);
for(int k=0;k<m;++k) for(int l=k+1;l<m;++l) {
memset(num, 0, 26*26*26*26*sizeof(int));
for(int i=0;i<n;++i){
int h = 0;
for(int j=0;j<m;++j) if (j!=k && j!=l) h = h * 26 + s[i][j] - 'a';
ans += num[h];
++num[h];
}
}
for(int k=0;k<m;++k) {
memset(num, 0, sizeof(num));
for (int i=0;i<n;++i) {
int h=0;
for (int j=0;j<m;++j) if (j!=k) h=h*26+s[i][j]-'a';
ans -= (long long)(num[h]) * (m-2);
++num[h];
}
}
qsort(s, n, 7, cmp);
for(int i=1;i<n;++i){
if (memcmp(s[i],s[i-1],m)) c += (long long)tmp*(tmp-1)/2, tmp=1;
else ++tmp;
}
if (tmp) c += (long long)tmp*(tmp-1)/2;
ans += c * (m-1) * (m-2) / 2;
printf("%lld\n", ans);
}
下面是时间复杂度是
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int n, m, num[26*26*26*26*26], tmp=1;
int op[(int)2e5], ops;
char s[(int)2e5][7];
long long ans, c;
int cmp(const void *a, const void *b) {return memcmp(a, b, m);}
int main() {
scanf("%d %d", &n, &m);
for(int i=0;i<n;++i) scanf("%s", s[i]);
for(int k=0;k<m;++k) for(int l=k+1;l<m;++l) {
while (ops) --num[op[--ops]];
for(int i=0;i<n;++i){
int h = 0;
for(int j=0;j<m;++j) if (j!=k && j!=l) h = h * 26 + s[i][j] - 'a';
ans += num[h];
++num[h];
op[ops] = h;
++ops;
}
}
for(int k=0;k<m;++k) {
while (ops) --num[op[--ops]];
for (int i=0;i<n;++i) {
int h=0;
for (int j=0;j<m;++j) if (j!=k) h=h*26+s[i][j]-'a';
ans -= (long long)(num[h]) * (m-2);
++num[h];
op[ops] = h;
++ops;
}
}
qsort(s, n, 7, cmp);
for(int i=1;i<n;++i){
if (memcmp(s[i],s[i-1],m)) c += (long long)tmp*(tmp-1)/2, tmp=1;
else ++tmp;
}
if (tmp) c += (long long)tmp*(tmp-1)/2;
ans += c * (m-1) * (m-2) / 2;
printf("%lld\n", ans);
}