JZOJ 4058. 【JSOI2015】子集选取

来源:互联网 发布:淘宝运营策划案 编辑:程序博客网 时间:2024/06/05 09:40

Description

Description

Input

Input

Output

Output

Sample Input

输入1:

2 2

输入2:

6 40

Sample Output

输出1:

16

输出2:

401898087

Data Constraint

Data Constraint

Solution

  • fnk 为输入为 nk 的答案。

  • 由于对于每一个元素,选取过程都是独立的,

  • 即元素 i 不会影响元素 j 的选取

  • 那么可以得到 fnk=f1kn

  • 下面来推导 f1k 。单个元素的选取的特点是:

  • 选取 1 的位置是连续的,并会形成阶梯状。

  • 如下图:(当 k=6的情况:深色的是被选取的部分)

Solution

  • Ai 为第 i 列最后选取的行是什么。若从第 1 列到第 m 列均存在格子被选取,

  • 那么将满足:

    Ai+1Ai1im

  • Gi,j 表示在第 i 列最后选取的是第 j 行的方案数,那么得到递推式:

    Gi,j=p=jkGi1p

  • 观察可得:

    Gi,j=Gi1j+Gij+1

  • 推导一下会发现这是组合数的形式!

  • 由于元素可以一个也不选,也可以在任意位置结束,所以:

    f1k=1+Gi,j=2k

  • 综合可得:

    fnk=2nk

  • 则时间复杂度为 Ologn

Code

#include<cstdio>using namespace std;const int mo=1e9+7;int n,k;inline long long ksm(long long x,int y){    long long s=1;    while(y)    {        if(y&1) s=s*x%mo;        x=x*x%mo;        y>>=1;    }    return s;}int main(){    scanf("%d%d",&n,&k);    printf("%lld",ksm(ksm(2,k),n));    return 0;}
1 0