题1:https://www.luogu.com.cn/problem/P1641
分析:总的减去不合法的,总:C(n+m,m),不合法(n+m,m-1),前者从(0,0)到达(n+m,n-m),后者可以看作从(0,-2)到达(n+m,n-m)
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back const int inf=0x3f3f3f3f; const ll INF=1e18; const int mod=20100403; ll ksm(ll x,ll y){ ll t=1; while(y){ if(y&1) t=(t*x)%mod; x=(x*x)%mod; y>>=1; } return t; } void pn(){ cout<<"No"<<' '; } void py(){ cout<<"Yes"<<' '; } int main(){ ll n,m; scanf("%lld%lld",&n,&m); ll fen1=1ll,mu1=1ll; ll now=n+m; for(ll i=1;i<=m;i++,now--){ fen1*=now,fen1%=mod; mu1*=i,mu1%=mod; } ll fen2=1ll,mu2=1ll; now=n+m; for(ll i=1;i<=m-1;i++,now--){ fen2*=now,fen2%=mod; mu2*=i,mu2%=mod; } printf("%lld ",(fen1*ksm(mu1,mod-2)%mod-fen2*ksm(mu2,mod-2)%mod+mod)%mod); return 0; }
题2:https://ac.nowcoder.com/acm/contest/5477/E
分析:ans=合法方案/全部方案,合法方案:卡特兰数C(2n,n)/(n+1),全部方案:每次从2∗n个数里选两个然后从2∗n−2里再选两个,直到选完为止然后从2*n-2里再选两个。但是这样会出现重复状态,就需要再除以n!,所以为C(2n,2)*C(2n-2,2)....C(2,2)/n!。
最后化简得:ans=2^n/(n+1)!
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back const int inf=0x3f3f3f3f; const ll INF=1e18; const int M=2e6+3; const int mod=1e9+7; ll ksm(ll x,ll y){ ll t=1; while(y){ if(y&1) t=(t*x)%mod; x=(x*x)%mod; y>>=1; } return t; } void pn(){ cout<<"NO"<<' '; } void py(){ cout<<"YES"<<' '; } int main(){ ios::sync_with_stdio(false); cin.tie(0); ll n; cin>>n; ll ans=ksm(2,n); ll res=1ll; for(ll i=2;i<=n+1;i++) (res*=i)%=mod; cout<<(ans*ksm(res,mod-2))%mod<<endl; return 0; }