http://acm.pku.edu.cn/JudgeOnline/problem?id=1240
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_M 20
long binomial[MAX_M+1][MAX_M+1];
void build_binomial(int m)
{
int i, j;
binomial[0][0] = 1;
for (i = 1; i <= m; i++) {
binomial[i][0] = binomial[i][i] = 1;
for (j = 1; j <= i-1; j++) {
binomial[i][j] = binomial[i-1][j] + binomial[i-1][j-1];
}
}
}
void calc_children(char *pre, int start, int len, int *descendants,
int *children)
{
int root = pre[start];
int i, subtree_len;
children[root] = 0;
for (i = 1; i < len; ) {
children[root]++;
subtree_len = 1 + descendants[pre[start+i]];
calc_children(pre, start+i, subtree_len, descendants, children);
i += subtree_len;
}
}
int main(void)
{
int m;
char pre[27], post[27];
char pre_cmp[256][256], post_cmp[256][256];
int descendants[256], children[256];
int i, j, len;
long ans;
while (scanf("%d", &m) == 1 && m) {
scanf("%s %s", pre, post);
build_binomial(m);
for (i = 0; i < 256; i++) {
memset(pre_cmp[i], 0, 256);
memset(post_cmp[i], 0, 256);
}
len = strlen(pre);
for (i = 0; i < len; i++) {
for (j = i+1; j < len; j++) {
pre_cmp[pre[i]][pre[j]] = 1;
post_cmp[post[i]][post[j]] = 1;
}
}
for (i = 'a'; i < 'a' + len; i++) {
descendants[i] = 0;
for (j = 'a'; j < 'a' + len; j++) {
if (pre_cmp[i][j] && post_cmp[j][i]) {
descendants[i]++;
}
}
}
calc_children(pre, 0, len, descendants, children);
ans = 1;
for (i = 'a'; i < 'a' + len; i++) {
ans *= binomial[m][children[i]];
}
printf("%ld\n", ans);
}
return 0;
}