背景:手瓢打错了组合数与期望,但是却神奇地AC了,还是机房首A,后来写题解时发现不对劲,不知道为什么对,求救
问题简化(左正解,右神奇的解法):求证
C(kn)∑i=1kC(k−in−1−i)i=i=1∑k(k−i)!(n−i)!n!k!即为什么s1=s2,或者说有什么第三个没有发现的问题
#include<bits/stdc++.h>
using namespace std;
namespace s1{
#define int long long
#define it long long
constexpr int N = 1e6 + 5, M = 998244353;
int p[N], ans, pt;
inline int qpow(int a, int x){
int ans = 1;
while(x){
if(x & 1) ans = (it)ans * a % M;
a = (it)a * a % M;
x >>= 1;
} return ans;
}
inline int inv(int x){
return qpow(x, M-2);
}
inline int P(int a, int b){
return (it)p[a] * inv(p[b]) % M;
}
signed solution(int n,int k){
memset(p,0,sizeof(p));
ans=0,pt=0;
p[0] = 1; for(int i=1; i<=n; ++i) p[i] = (it)p[i-1] * i % M;
pt = inv(P(n, k));
for(int i=1; i<=k; ++i)
ans = ((it)ans + (it)P(n-i, k-i) * pt % M) % M;
return ans;
}
#undef it
#undef int
}
namespace s2{
#define int long long
using namespace std;
const int modd=998244353;
int x,y,jie[1000010],ni[1000010],ans1,ans2;
void exgcd(int q,int w){
if(w==0){
x=1;
y=0;
return;
}
exgcd(w,q%w);
int t=x;
x=y;
y=t-(q/w)*x;
return;
}
int C(int q,int w){
if(q<w){
return 1;
}
return jie[q]*ni[w]%modd*ni[q-w]%modd;
}
signed solution(int n,int m){
jie[0]=1;
ni[0]=1;
for(int i=1;i<=1000000;i++){
jie[i]=jie[i-1]*i%modd;
exgcd(jie[i],modd);
ni[i]=(x%modd+modd)%modd;
}
x=0,y=0,ans1=0,ans2=0;
if(n==m){
return(n);
}
for(int i=1;i<=m+1;i++){
ans1=ans1+(i-1)*C(n-i,m-i+1);
ans1%=modd;
}
ans2=C(n,m);
exgcd(ans2,modd);
int ans=(ans1*x%modd+modd)%modd;
return ans;
}
}
signed main(){
cin>>n>>k;
cout<<s1::solution(n,k)<<endl<<s2::solution(n,k)<<endl;
}
题目: