【BZOJ4475】 [Jsoi2015]子集选取

题目描述

img

数据范围

\(1\leq N,K \leq 10^9\)

\(solution\)

集合S中每个元素互不影响,不妨依次考虑其中一个元素在三角形中的出现情况

问题转化为一个\(0/1\)的三角形\(\{A_{i,j}\}\),用\(0\)表示选了,\(1\)表示没选,那么如果\(A_{i,j}\)\(1\),则\(A_{i,j}\)左边和上边都是\(1\)

考虑\(n\)比较小的情况,可以DP

\(f_i\)表示一个\(i*i\)的三角形的方案数

对于\(f_i\),第\(i\)行一定是一段\(1\)和一段\(0\)拼起来,枚举\(1\)的长度\(j\),前\(j\)列的元素都必须选\(1\),其他列除去第\(i\)行构成一个长为\((i-j-1)\)的三角形,填法为\(f_{i-j-1}\)

最后加上是第\(i\)行全选\(1\)的情况,只有\(1\)

\(f_i=1+\sum_{j=0}^{i-1}f_{i-j-1}=1+\sum_{j=0}^{i-1}f_j\)

\(f_0=1\)

不妨令\(S_i=\sum_{j=0}^if_j\)

原式\(f_i=1+S_{i-1}\)\(S_{i-1}=f_i-1\)

则有

\(S_i-S_{i-1}=(f_{i+1}-1)-(f_i-1)\)

\(f_i=f_{i+1}-f_{i}\)

\(f_{i+1}=2*f_i\)\(f_0=1\)

\(f_n=2^n\)

\(ans={f_n}^k=2^{nk}\)

#include<iostream>
#include<cstring>
#include<cstdio>
#define int long long
using namespace std;

const int MOD=1000000007;

int n,k;

inline int qpow(int x,int k){
	int s=1;
	while(k){
		if(k&1) s=s*x%MOD;
		k>>=1;
		x=x*x%MOD;
	}
	return s;
}

signed main()
{
	scanf("%lld%lld",&n,&k);
	printf("%lld\n",qpow(2,n*k));
	return 0;
}
posted @ 2019-10-21 11:19  yjk  阅读(131)  评论(0编辑  收藏  举报