Balanced Subsequences

liyixin發表於2024-10-15

Balanced Subsequences

注意子序列不一定連續。

恰好最長合法括號子序列長度為 \(2k\),那麼廢掉的 ) 個數為 \(m-k\)

恰好的方案數 \(f_k\) 不好求,我們可以求 \(g_k\) 表示長度至少為 \(2k\) 的方案數。

( 表示向上走,) 表示向下走,\(g_k\) 即為從 \((0,0)\) 走到 \((n+m,n-m)\),且廢掉的右括號數 \(-y\le m-k\),即不超過直線 \(y=k-m\)

\(g_k=\binom{n+m}{n}-\binom{n+m}{k-1}\)

\(f_k=g_k-g_{k+1}=\binom{n+m}{k}-\binom{n+m}{k-1}\)

注意判無解 \(k> \min(n,m)\)

時間複雜度 \(O(n+m)\)

Code

#include<bits/stdc++.h>
#define sf scanf
#define pf printf
using namespace std;
typedef long long ll;
const int N=2e3+5,mxx=N<<2,mod=1e9+7;
int t;
ll jc[mxx+5],inv[mxx+5];
ll ksm(ll a,ll b){
	ll s=1;
	while(b){
		if(b&1){
			s=s*a%mod;
		}
		a=a*a%mod;
		b>>=1;
	}
	return s;
}
void init(){
	jc[0]=1;
	for(int i=1;i<=mxx;i++){
		jc[i]=jc[i-1]*i%mod;
	}
	inv[mxx]=ksm(jc[mxx],mod-2);
	for(int i=mxx-1;i>=0;i--){
		inv[i]=inv[i+1]*(i+1)%mod;
	}
}
int n,m,k;
ll C(ll n,ll m){
	if(m>n) return 0; 
	return jc[n]*inv[n-m]%mod*inv[m]%mod;
}
int main(){
	init();
	sf("%d",&t);
	while(t--){
		sf("%d%d%d",&n,&m,&k);
		if(k>min(n,m)) {
			pf("0\n");
			continue;
		}
		pf("%lld\n",(C(n+m,k)-C(n+m,k-1)+mod)%mod);
	}
}