A. Hard to prepare
题意:有n个客人做成一圈,有$2^k$种面具,对于每种面具有一种面具不能使相邻的两个人戴,共有多少种做法。
思路: 把题意转化成相邻的人不能带同种面具。总数为$(2^k)^n$,减去一对相邻的客人戴同种面具$(2^k)^{(n-1)}*C(n,1)$,其中重复了两对相邻的客人戴同种面具$(2^k)^{(n-2)}*C(n,2)$,依次容斥。
最后所有人都戴同种面具的情况额外考虑,当n是奇数时,n-1对客人相同即所有人相同。n为偶数时,n-1对客人相同时用公式有重复的一轮,所以要加上。
设t=2^k
$\sum_{i = 0}^{i = n - 1} C_n^i \cdot t^{n - 1} * (-1)^i$ (n 是奇数)
$\sum_{i = 0}^{i = n - 1} C_n^i \cdot t^{n - 1} * (-1)^i + t$ (n 是偶数)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 #define N 1000010 6 7 const ll MOD = (ll)1e9 + 7; 8 9 int t, n, k; 10 ll inv[N]; 11 ll Bit[N]; 12 ll Bitt[N]; 13 14 inline void Init() 15 { 16 inv[1] = 1; 17 for (int i = 2; i < N; ++i) inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD; 18 Bit[0] = 1; 19 for (int i = 1; i < N; ++i) Bit[i] = (Bit[i - 1] * 2) % MOD; 20 } 21 22 inline void init() 23 { 24 Bitt[0] = 1; ll tmp = Bit[k]; 25 for (int i = 1; i <= n; ++i) Bitt[i] = (Bitt[i - 1] * tmp) % MOD; 26 } 27 28 inline void Run() 29 { 30 scanf("%d", &t); Init(); 31 while (t--) 32 { 33 scanf("%d%d", &n, &k); 34 if (k == 1) 35 { 36 puts("2"); 37 continue; 38 } 39 else if (n == 1) 40 { 41 printf("%lld\n",Bit[k]); 42 continue; 43 } 44 init(); 45 ll res = 0; 46 ll C = 1; 47 for (int i = 0; i < n; ++i) 48 { 49 res = (res + (C * Bitt[n - i] % MOD * ((i & 1) ? -1 : 1) + MOD) % MOD) % MOD; 50 C = C * (n - i) % MOD * inv[i + 1] % MOD; 51 } 52 res = (res + (Bit[k] * ((n & 1) ? 0 : 1)) % MOD + MOD) % MOD; 53 printf("%lld\n", res); 54 } 55 } 56 57 int main() 58 { 59 #ifdef LOCAL 60 freopen("Test.in", "r", stdin); 61 #endif 62 63 Run(); 64 return 0; 65 }