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

JZOJ 4058. 【JSOI2015】子集选取

2017-02-11 20:48 253 查看

Description



Input



Output



Sample Input

输入1:

2 2

输入2:

6 40

Sample Output

输出1:

16

输出2:

401898087

Data Constraint



Solution

设 f(n,k) 为输入为 n,k 的答案。

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

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

那么可以得到 f(n,k)=f(1,k)n 。

下面来推导 f(1,k) 。单个元素的选取的特点是:

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

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



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

那么将满足:Ai+1≤Ai(1≤i≤m)

设 Gi,j 表示在第 i 列最后选取的是第 j 行的方案数,那么得到递推式:Gi,j=∑p=jkGi−1,p

观察可得:Gi,j=Gi−1,j+Gi,j+1

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

由于元素可以一个也不选,也可以在任意位置结束,所以:f(1,k)=1+∑Gi,j=2k

综合可得:f(n,k)=2n∗k

则时间复杂度为 O(logn) !

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: