标签:return const include -- size main c++ 组合数 连线
题目分析:
我们思考正好被k个区间覆盖的情况,那么当前这个子段是不是把所有的点分成了两个部分,那么在两个部分之间相互连k条线,再对于剩下的分别连线就很好了?这个东西不难用组合数写出来。
然后我们要证明每个区间的期望长度是点数加一分之一,这个很容易,归纳法证明就行了。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int mod = 998244353; 5 6 int n,k,l; 7 int f[10200]; 8 int fac[10200],inv[10200],pw[10200]; 9 10 int C(int nn,int kk){ 11 return 1ll*fac[nn]*inv[kk]%mod*inv[nn-kk]%mod; 12 } 13 int A(int nn,int kk){ 14 return 1ll*fac[nn]*inv[nn-kk]%mod; 15 } 16 17 int fast_pow(int now,int pw){ 18 int ans = 1,dt = now,bit = 1; 19 while(bit <= pw){ 20 if(bit & pw){ans = 1ll*ans*dt%mod;} 21 dt = 1ll*dt*dt%mod; bit<<=1; 22 } 23 return ans; 24 } 25 26 int work(int rm){ 27 int ll = 0,r = 2*n;int Rp = fast_pow(f[2*n],mod-2); 28 int ans = 0; 29 while(r>=0){ 30 int now = C(ll,rm),im = A(r,rm); 31 int res = 1ll*now*im%mod*f[ll-rm]%mod*f[r-rm]%mod*pw[rm]%mod; 32 res = 1ll*res*Rp%mod; 33 ans += res; ans%=mod; 34 ll++; r--; 35 } 36 ans = 1ll*ans*fast_pow(2*n+1,mod-2)%mod*l%mod; 37 return ans; 38 } 39 40 int main(){ 41 scanf("%d%d%d",&n,&k,&l); 42 f[0] = 1;fac[0] = 1;pw[0] = 1; 43 for(int i=1;i<=2*n;i++) pw[i] = 2*pw[i-1]%mod,fac[i] = 1ll*fac[i-1]*i%mod; 44 for(int i=2;i<=2*n;i++){ 45 f[i] = 2ll*f[i-2]%mod*(i-1)%mod; 46 } 47 inv[2*n] = fast_pow(fac[2*n],mod-2); 48 for(int i=2*n-1;i>=0;i--) inv[i] = 1ll*inv[i+1]*(i+1)%mod; 49 int ans = 0; 50 for(int i=k;i<=n;i++) ans += work(i),ans%=mod; 51 printf("%d\n",ans); 52 return 0; 53 }
Codeforces1153F Serval and Bonus Problem 【组合数】
标签:return const include -- size main c++ 组合数 连线
原文地址:https://www.cnblogs.com/Menhera/p/10778281.html