您的位置:首页 > Web前端 > JavaScript

BZOJ4475 [Jsoi2015]子集选取

2018-03-06 09:46 211 查看

Description

有一些\(\{1\dots n\}\)的子集\(A_{i,j}, 1\leq j\leq i\leq 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}\neq B_{i,j}\),则它们是不同的。\(n, k\leq 10^9\)

Solution

对于\(n=1\)求出方案数,之后将这个方案数取\(n\)次幂即可。因为不同的元素之间是互不影响的。

\(n=1\)时,我实际上要从
\[ \begin{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\n", ans) & 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: