标签:printf using 大于 print 其他 name const 选择 while
这道题有点坑啊,
首先先化简一下题意吧:
有\(n\)个人,你得选至少k个人组成足球队,在从足球队里选出精英队,最后从精英队中选出一位队长,问不同方案有多少种。
假如选\(i\)个人组成足球队,方案为\(C_n^i\)种,从\(i\)个人中选一人做队长,有\(i\)种选择,选出其他精英队的队员,每个人有选、不选两种选择,方案数\(2^{i-1}\)
所以总方案数:\(\sum_{i=k}^n \binom{n}{i}*i*2^{i-1} (\bmod 8388608)\)
到目前为止都很正常,问题来了,如何优化呢?
你会惊奇的发现\(mod=2^23\),当\(i\)大于23时,\(2^{i-1} \bmod 8388608 =0\),所以\(i\)只要枚举到23就行了.
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=8388608,N=1e5+6;
int t,k;
ll n,inv[27],ans=0,c[N][25],pw;
int main(){
scanf("%d",&t),c[0][0]=1;
for(int i=1;i<=1e5;++i){
c[i][0]=1;
for(int j=1;j<=min(23,i);++j) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
while(t--){
scanf("%lld%d",&n,&k),pw=1,ans=0;
for(ll i=1;i<=min(23,k);++i) ans=(ans+c[n][i]*i%mod*pw%mod)%mod,pw<<=1ll;
printf("%lld\n",ans);
}
return 0;
}
标签:printf using 大于 print 其他 name const 选择 while
原文地址:https://www.cnblogs.com/ljk123-de-bo-ke/p/11838285.html