【Codechef】CNTL
题面
题解
第一问直接考虑一下\(N,K\)的奇偶性即可,当他们奇偶性相同,答案就是\(2^K-1\),否则是\(2^K-2\)。
第二问因为是排列问题考虑指数型生成函数,那么当答案为\(2^K-1\)时,答案为\([x^n](\frac{e^x-e^{-x}}{2})^K\),否则为\([x^n][(\frac{e^x-e^{-x}}{2})^{K-1}\times \frac{e^x+e^{-x}}{2}]\)
最后把这两个式子二项式展开一下就完事儿了。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
const int Mod = 1e9 + 7;
const int MAX_N = 1e5 + 5;
int fpow(int x, int y) {
int res = 1;
while (y) {
if (y & 1) res = 1ll * res * x % Mod;
x = 1ll * x * x % Mod;
y >>= 1;
}
return res;
}
int N = 1e5, K, fac[MAX_N], ifc[MAX_N];
int C(int n, int m) {
if (n < 0 || m < 0 || n < m) return 0;
else return 1ll * fac[n] * ifc[m] % Mod * ifc[n - m] % Mod;
}
int main () {
fac[0] = 1; for (int i = 1; i <= N; i++) fac[i] = 1ll * fac[i - 1] * i % Mod;
ifc[N] = fpow(fac[N], Mod - 2);
for (int i = N - 1; ~i; i--) ifc[i] = 1ll * ifc[i + 1] * (i + 1) % Mod;
int Q = gi();
while (Q--) {
N = gi(), K = gi();
if ((N ^ K) & 1) {
int ans = 0;
for (int i = 0, op = fpow(Mod - 1, K - 1); i < K; i++, op = Mod - op)
ans = (ans + 1ll * op * C(K - 1, i) % Mod *
(fpow(2 * i - K + 2 + Mod, N) + fpow(2 * i - K + Mod, N))) % Mod;
printf("%d %lld\n", fpow(2, K) - 2, 1ll * ans * fpow(fpow(2, K), Mod - 2) % Mod);
} else {
int ans = 0;
for (int i = 0, op = fpow(Mod - 1, K); i <= K; i++, op = Mod - op)
ans = (ans + 1ll * op * C(K, i) % Mod * fpow(2 * i - K + Mod, N)) % Mod;
printf("%d %lld\n", fpow(2, K) - 1, 1ll * ans * fpow(fpow(2, K), Mod - 2) % Mod);
}
}
return 0;
}