题解:P6811 「MCOI-02」Build Battle 建筑大师
CharlieCai · · 题解
设
由于本题
继续考虑如何优化,我们对
想想如何快速求出
-
让
i+1 \to i ,花费代价v=2\times lastv ; -
让
i+m+1 \to i ,花费代价v=-lastv ;
最后答案
于是有
接下来只要枚举
#include<bits/stdc++.h>
#define MAXN 2000005
#define int long long
using namespace std;
const int inf=1e18,mod=1e9+7;
int fpow(int a,int b){
int tans=1;
while(b){
if(b&1)tans=tans*a%mod;
a=a*a%mod;
b>>=1;
}
return tans;
}
int n,q,a[MAXN],ans[MAXN];
int fac[MAXN],ifac[MAXN],p[MAXN];
void init(){
fac[0]=ifac[0]=p[0]=1;
for(int i=1;i<=n*2;i++){
fac[i]=fac[i-1]*i%mod;
ifac[i]=ifac[i-1]*fpow(i,mod-2)%mod;
p[i]=p[i-1]*2%mod;
}
}
int C(int n,int m){
if(n<m)return 0;
return fac[n]*ifac[n-m]%mod*ifac[m]%mod;
}
signed main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
scanf("%lld%lld",&n,&q);
init();
for(int i=1;i<=n;i++){
int m=i;
for(int j=0;j<=n/(m+1);j++){
if(j&1)ans[m]=(ans[m]+mod-p[n-j*(m+1)]*C(n-j*(m+1)+j,j)%mod)%mod;
else ans[m]=(ans[m]+p[n-j*(m+1)]*C(n-j*(m+1)+j,j)%mod)%mod;
}
}
for(int i=1;i<=q;i++){
int x;scanf("%lld",&x);
printf("%lld\n",ans[x]);
}
return 0;
}