【OJ3023】集合

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));
}

猜你喜欢

转载自www.cnblogs.com/farway17/p/9347112.html
OJ