Description
内部题目,不放链接了。
Solution
类似于状压 \(dp\),我们对于每一位分别处理。
判断同一个父节点的两个儿子,若对应位字母相同,则不处理。
若不同,就把状态 或 起来,并把差异值加一。
然后……就没有然后了。
这题可以用 \(bitset\) 维护。
Code
#include <iostream>
#include <cstdio>
#include <bitset>
using namespace std;
const int N = 1030;
int n, m, ans;
char s[N][N];
bitset <26> f[N];
void solve(int x){
for(int i = 1; i <= n; i++)
f[i].reset(), f[i][s[i][x] - 'A'] = 1;
for(int i = (n >> 1); i; i >>= 1)
for(int j = 1; j <= i; j++){
int l = (j << 1) - 1, r = j << 1;
if((f[l] & f[r]).count()) f[j] = f[l] & f[r];
else f[j] = f[l] | f[r], ans++;
}
for(int i = 0; i < 26; i++)
if(f[1][i]){
putchar(i + 'A');
break;
}
return;
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%s", s[i]);
for(int i = 0; i < m; i++)
solve(i);
printf(" %d\n", ans);
return 0;
}