public long count(int N, int M, int K) { int i, j, k; int len = N - M + 1; long res = 0; if (K == 0) { return((long)(Math.Pow(26, N) + 1e-9)); } long[] mul = new long[len + 1]; if (len >= K) { mul[K] = 1; } for (i = K + 1; i <= len; i++) { long now = 0; for (j = 0; j < i; j++) { now -= c(i, j) * mul[j]; } mul[i] = now + 1; } for (i = 0; i < (1 << len); i++) { int count = 0; Unionfind uni = new Unionfind(N); for (j = 0; j < len; j++) { if ((i >> j) % 2 == 1) { count++; for (k = 0; k <= (M - 1) / 2; k++) { uni.connect(j + k, j + M - k - 1); } } } if (K > count) { continue; } long now = 1; for (j = 0; j < N; j++) { if (uni.root(j) == j) { now *= 26; } } res += now * mul[count]; } return(res); }
public long count(int N, int M, int K) { int i, j, k; int len = N - M + 1; long res = 0; if (K == 0) return (long)(Math.Pow(26, N) + 1e-9); long[] mul = new long[len + 1]; if (len >= K) mul[K] = 1; for (i = K + 1; i <= len; i++) { long now = 0; for (j = 0; j < i; j++) { now -= c(i, j) * mul[j]; } mul[i] = now + 1; } for (i = 0; i < (1 << len); i++) { int count = 0; Unionfind uni = new Unionfind(N); for (j = 0; j < len; j++) { if ((i >> j) % 2 == 1) { count++; for (k = 0; k <= (M - 1) / 2; k++) { uni.connect(j + k, j + M - k - 1); } } } if (K > count) continue; long now = 1; for (j = 0; j < N; j++) { if (uni.root(j) == j) { now *= 26; } } res += now * mul[count]; } return res; }