1. 程式人生 > 其它 >「NOIP2021模擬賽8.19 A」集合(set)題解

「NOIP2021模擬賽8.19 A」集合(set)題解

題目大意

「NOIP2021模擬賽8.19 A」集合(set)

給定一個包含\(n\)個元素的集合\(S\),請找出\(k\)個可以相等的子集\(S_1,S_2,...,S_k\)使得交集是空集,求滿足條件的方案數

問題求解

我們依次考慮每個數包含在那些集合中,顯然為了使所有集合相交為空集,它不能被所有集合都包含,其他的情況都是可以的,因此考慮每個數的方案數是\(2^k-1\),容易發現不同的數之間互不影響,所以答案就是\((2^k-1)^n\)

然後對於\(n,k≤10^{63}\)我們可以考慮用高精度來處理,但如果不想寫高精度的話可以考慮用尤拉定理來實現

\[a^{\varphi(n)}\equiv1 \]

所以我們在\(n,k\)

讀入時摸\(\varphi(n)\)也就是\(mod-1\)就好了

程式碼實現

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL TT=1e9+7;
LL n,k;
LL QSM(LL a,LL b){
	LL s=1,w=a;
	while(b){
		if(b&1)s=s*w%TT;
		w=w*w%TT;
		b>>=1;
	}
	return s;
}
LL read(){
	LL ret=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ret%=TT-1,ch=getchar();
	return ret*f;
}
int main(){
	freopen("set.in","r",stdin);
	freopen("set.out","w",stdout);
	n=read();k=read();
	printf("%lld\n",QSM((QSM(2,k)+TT-1)%TT,n));
	return 0;
}