BZOJ4475[Jsoi2015]子集选取——递推(结论题)

怼烎@ 2022-01-05 15:09 238阅读 0赞

题目描述

11_282_29.png

输入

输入包含一行两个整数N和K,1<=N,K<=10^9

输出

一行一个整数,表示不同方案数目模1,000,000,007的值。

样例输入

2 2

样例输出

16

可以发现对于集合中每个元素的选取都是互不影响的,设$f(n,k)$为输入$n,k$时的答案,那么$f(n,k)=f(1,k)^n$。

我们现在来推导$f(1,k)$的结果:可以发现$1$的位置一定是连续的,设$a_{i}$表示第$i$列最后选取到了$a_{i}$行,若从第$1$列到第$m$列均存在被选取。

那么可以得到结论:$a_{i+1}\le a_{i}(1\le i <m)$。

设$g[i][j]$表示只有前$i$列有$1$,其中第$i$列最后选取到了第$j$行的方案数,可以得到递推式:$g[i][j]=\sum\limits_{p=j}^{k}g[i-1][p]$。

通过观察可以得到:$g[i][j]=g[i-1][j]+g[i][j+1]$,这实际上就是一个顺时针旋转了$45^{\circ}$的杨辉三角。

那么加上都不选取的方案数为$1$,$f(1,k)=1+\sum g[i][j]=2^k$,由此可得$f(n,k)=2^{nk}$。

  1. #include<set>
  2. #include<map>
  3. #include<queue>
  4. #include<cmath>
  5. #include<stack>
  6. #include<vector>
  7. #include<cstdio>
  8. #include<cstring>
  9. #include<iostream>
  10. #include<algorithm>
  11. #define ll long long
  12. using namespace std;
  13. int n,k;
  14. int mod=1000000007;
  15. ll quick(ll x,ll y)
  16. {
  17. ll res=1;
  18. while(y!=0)
  19. {
  20. if(y%2==1)
  21. {
  22. res=(res*x)%mod;
  23. }
  24. x=(x*x)%mod;
  25. y/=2;
  26. }
  27. return res%mod;
  28. }
  29. int main()
  30. {
  31. scanf("%d%lld",&n,&k);
  32. ll sum=1ll*n*k;
  33. printf("%lld",quick(2,sum));
  34. }

转载于:https://www.cnblogs.com/Khada-Jhin/p/10460244.html

发表评论

表情:
评论列表 (有 0 条评论,238人围观)

还没有评论,来说两句吧...

相关阅读

    相关 BZOJ1030 [JSOI2007] 文本生成器

    我再看错模数我就是呆头 考虑包含任意的补集不包含任何 然后典型的AC自动机上dp 长度为l不能走到任何关键点 特么模数多写了个0 问题是我刚跟zyf吐槽了模数 就当考前

    相关 [JSOI2007]麻将 模拟 BZOJ1028

    题目描述 麻将是中国传统的娱乐工具之一。麻将牌的牌可以分为字牌(共有东、南、西、北、中、发、白七种)和序数牌(分为条子、饼子、万子三种花色,每种花色各有一到九的九种牌),