Description
有一些({1dots n})的子集(A_{i,j}, 1leq jleq ileq k)共(frac{k(k+1)}2)个,满足(A_{i,j}subset A_{i+1,j}, A_{i,j}subset A_{i,j+1})。求这些集合有多少种方案。如果(A)和(B)两种方案中存在(i,j)使得(A_{i,j} eq B_{i,j}),则它们是不同的。(n, kleq 10^9)
Solution
对于(n=1)求出方案数,之后将这个方案数取(n)次幂即可。因为不同的元素之间是互不影响的。
(n=1)时,我实际上要从
[egin{matrix}
A_{1,1}\
A_{2,1}&A_{2,2}\
A_{3,1}&A_{3,2}&A_{3,3}\
vdots&vdots&vdots&ddots\
A_{k,1}&A_{k,2}&A_{k,3}&cdots&A_{k,k}
end{matrix}
]
这个三角中选出一些来包含(1)。
那么,我从这个矩阵左下角即(A_{k,1})的左下方开始,每次向右或上走一步,直到某个(A_{i,i})的左上角(或者(A_{k,k})的右下角);走出这个折线的右下的集合包含(1),其它不包含(1)。那么我一共会走((k-i+1)+(i-1)=k)步,每步可以向右/下走,所以共有(2^k)种方案。
综上,答案即为(2^{nk})。
Code
#include <cstdio>
typedef long long LL;
const int mod = 1000000007;
int main() {
int n, k;
scanf("%d%d", &n, &k);
int ans = 1, x = 2;
for (n = (LL)n * k % (mod - 1); n; n >>= 1, x = (LL)x * x % mod)
if (n & 1) ans = (LL)ans * x % mod;
return printf("%d
", ans) & 0;
}