Codeforces1153F Serval and Bonus Problem 【组合数】

题目分析:

我们思考正好被k个区间覆盖的情况,那么当前这个子段是不是把所有的点分成了两个部分,那么在两个部分之间相互连k条线,再对于剩下的分别连线就很好了?这个东西不难用组合数写出来。

然后我们要证明每个区间的期望长度是点数加一分之一,这个很容易,归纳法证明就行了。

代码:

 #include<bits/stdc++.h>
using namespace std; const int mod = ; int n,k,l;
int f[];
int fac[],inv[],pw[]; int C(int nn,int kk){
return 1ll*fac[nn]*inv[kk]%mod*inv[nn-kk]%mod;
}
int A(int nn,int kk){
return 1ll*fac[nn]*inv[nn-kk]%mod;
} int fast_pow(int now,int pw){
int ans = ,dt = now,bit = ;
while(bit <= pw){
if(bit & pw){ans = 1ll*ans*dt%mod;}
dt = 1ll*dt*dt%mod; bit<<=;
}
return ans;
} int work(int rm){
int ll = ,r = *n;int Rp = fast_pow(f[*n],mod-);
int ans = ;
while(r>=){
int now = C(ll,rm),im = A(r,rm);
int res = 1ll*now*im%mod*f[ll-rm]%mod*f[r-rm]%mod*pw[rm]%mod;
res = 1ll*res*Rp%mod;
ans += res; ans%=mod;
ll++; r--;
}
ans = 1ll*ans*fast_pow(*n+,mod-)%mod*l%mod;
return ans;
} int main(){
scanf("%d%d%d",&n,&k,&l);
f[] = ;fac[] = ;pw[] = ;
for(int i=;i<=*n;i++) pw[i] = *pw[i-]%mod,fac[i] = 1ll*fac[i-]*i%mod;
for(int i=;i<=*n;i++){
f[i] = 2ll*f[i-]%mod*(i-)%mod;
}
inv[*n] = fast_pow(fac[*n],mod-);
for(int i=*n-;i>=;i--) inv[i] = 1ll*inv[i+]*(i+)%mod;
int ans = ;
for(int i=k;i<=n;i++) ans += work(i),ans%=mod;
printf("%d\n",ans);
return ;
}
上一篇:An invalid character [32] was present in the Cookie value


下一篇:在ubuntu上建立多svn版本库