A
题意
有 n n n 个人围成圆形而坐, 2 k 2^k 2k 顶帽子,一顶帽子可以给任意多个人,一个人只能由一顶帽子,帽子的编号为 [ 0 , 2 k − 1 ] [0,\ 2^k-1] [0, 2k−1] 。相邻两个人帽子的编号不能在k位上都相反,问有多少种坐的办法。
思路
相邻问题链上好分析,但是因为本题要求是围成一个圆坐,所以要考虑链的两端能否满足条件。又由按位取反操作可知,对于任意一个人,有且仅有唯一与之对应的一个人不能邻座,而且这种不能邻座的关系是互相的。那么我们定义
d
p
[
i
]
[
0
]
dp[i][0]
dp[i][0] 表示第
i
i
i 个人与第一个人帽子编号相同时的方案数,
d
p
[
i
]
[
1
]
dp[i][1]
dp[i][1] 表示第
i
i
i 个人编号为第一个人位按位取反时的方案数,
d
p
[
i
]
[
0
]
dp[i][0]
dp[i][0] 表示第
i
i
i 个人的帽子种类时其他时的方案数。那么得到状态转移方程
d
p
[
i
]
[
0
]
=
d
p
[
i
−
1
]
[
0
]
+
d
p
[
i
−
1
]
[
2
]
\quad dp[i][0]\quad = \quad dp[i-1][0] + dp[i-1][2]
dp[i][0]=dp[i−1][0]+dp[i−1][2]
d
p
[
i
]
[
1
]
=
d
p
[
i
−
1
]
[
1
]
+
d
p
[
i
−
1
]
[
2
]
\quad dp[i][1]\quad = \quad dp[i-1][1] + dp[i-1][2]
dp[i][1]=dp[i−1][1]+dp[i−1][2]
d
p
[
i
]
[
2
]
=
d
p
[
i
−
1
]
[
0
]
×
(
2
k
−
2
)
+
d
p
[
i
−
1
]
[
2
]
×
(
2
k
−
2
)
+
d
p
[
i
−
1
]
[
2
]
×
(
2
k
−
3
)
\quad dp[i][2]\quad = \quad dp[i-1][0]\times(2^k-2) + dp[i-1][2]\times(2^k-2) + dp[i-1][2]\times(2^k-3)
dp[i][2]=dp[i−1][0]×(2k−2)+dp[i−1][2]×(2k−2)+dp[i−1][2]×(2k−3)
代码
ll dp[maxn][3];
int main()
{
int T, n, k;
dp[0][0] = 1;
sd(T);
while(T--){
sdd(n, k);
ll tot = powmod(2, k);
rep(i, 1, n){
dp[i][0] = (dp[i-1][0] + dp[i-1][2])%mod;
dp[i][1] = (dp[i-1][1] + dp[i-1][2])%mod;
dp[i][2] = ((dp[i-1][0]+dp[i-1][1])*(tot-2)%mod + dp[i-1][2]*(tot-3))%mod;
}
ll ans = tot*(dp[n-1][0] + dp[n-1][2])%mod;
pld(ans);
}
return 0;
}