3023 -- 集合(Solution)
题目大意 : 有一个包含 \(N\) 个元素的集合 \(S\) ,找出 \(K\) 个集合 \(S_1,S_2…S_k\) (集合可以相等),满足:$ S_i(1≤i≤k)$ 是 \(S\) 的子集,且\(S_1∩S_2∩…∩S_k=∅\) ,求方案数。\((1\le N,K\le 10^{63}-1)\)
Tag: 计数
Analysis By LC:
对于每个数,对每个集合都有选或不选两种情况,排除全选的 \(1\) 种情况,故只有一个数的答案为 \(2^k-1\) .
\(n\) 个数,由于选择互不关联,根据乘法原理,最后答案为 \((2^k-1)^n\) .
使用快速幂即可得解。由于 \(n\) 和 \(k\) 都很大,可以用高精度或利用费马小定理得解。(p是质数,可推得\(a^b\) \(mod\) \(p=a^{b\, mod\, p-1}\) \(mod\) \(p\)).
Code By LC :
#include<cstdio>
typedef long long ll;
const ll Mod=1000000007;
char sn[105],sk[105]; ll n,k;
ll Pow(ll a, ll b)
{
ll ans=1;
while(b)
{
if(b&1) ans=(ans*a)%Mod;
a=(a*a)%Mod; b>>=1;
}
return ans;
}
int main()
{
scanf("%s%s",sn,sk);
for(int i=0;sn[i];i++)
n=(n*10+sn[i]-'0')%(Mod-1);
for(int i=0;sk[i];i++)
k=(k*10+sk[i]-'0')%(Mod-1);
ll tmp=(Pow(2,k)-1+Mod)%Mod;
printf("%lld",Pow(tmp,n));
}