恶臭数学题
题意
有(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('
');
}
}
}
int main () {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
Project::MAIN();
}