SP5973 SELTEAM - Selecting Teams

恶臭数学题


题意

\(n\)个人,从中选至多\(k\)个,再从\(k\)个人中选任意数量,在从这任意数量的人中选一个人,问:有多少种选法?(答案模8388608)

思路

式子很好推

\(ans=\sum_1^n(C_n^i * i * 2^{i-1})\)

但是这样计算的复杂度是\(O(n)\),再考虑到\(T\)组元素就是\(O(Tn)\),T得没边。

看上去这道题已经不可解了。

这个时候,我们可以发现模数不是一个质数。。。

进一步得到模数=\(2^{23}\),也就是说,从\(i=24\)开始都不用计算。那么最后的时间复杂度是\(O(23T)\),随便过。


代码

#include <bits/stdc++.h>

using namespace std;

namespace StandardIO {

	template<typename T>inline void read (T &x) {
		x=0;T f=1;char c=getchar();
		for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
		for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
		x*=f;
	}

	template<typename T>inline void write (T x) {
		if (x<0) putchar('-'),x*=-1;
		if (x>=10) write(x/10);
		putchar(x%10+'0');
	}

}

using namespace StandardIO;

namespace Project {
	
	const int MOD=8388608;
	
	int T,ans;
	int n,k;
	int c[100100][30];

	inline void MAIN () {
		for (register int i=0; i<=100000; ++i) {
			c[i][0]=1;
			for (register int j=1; j<=min(i,23); ++j) {
				c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD;
			}
		}
		read(T);
		while (T--) {
			read(n),read(k),ans=0;
			for (register int i=1; i<=min(k,23); ++i) {
				ans=(ans+1LL*((1<<(i-1))%MOD)*i*c[n][i])%MOD;
			}
			write(ans),putchar('\n');
		}
	}
	
}

int main () {
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	Project::MAIN();
}

posted @ 2019-07-17 21:04  Ilverene  阅读(225)  评论(0)    收藏  举报