[JSOI2015]子集选取 题解
洛谷地址
虽然是结论题,但是还是写一下总结回顾比较好
首先考虑一下 \(n=1\) 的情况,由于每个点的集合不能比左边和上边的大,所以就会出现有两个部分:
右下角的全都是 \(0\),左上角全都是 \(1\)
然后两个部分的分界线就是从左下角的点出发,走到斜边任意一点的一条路径了,我们发现每一步可以往右一格或者往上一格,一定会走 \(k\) 格
所以这样就是 \(2^k\)
然后扩展到 \(n\) 就是走了 \(n\) 条这样的路径,每一条路径的左上部分都包含 \(i\) 号元素,如果不包含,则该路径是一直往上的
那么就是 \((2^k)^n\)
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const ll mod=1000000007;
ll n,m;
inline ll ksm(ll x,ll k){
ll tmp=1;
while(k){
if(k%2==1)tmp*=x,tmp%=mod;
x=x*x%mod,k>>=1;
}
return tmp;
}
int main(){
cin>>n>>m;
cout<<ksm(2,n*m);
}