HDU

博主的 BiBi 时间

卡特兰数。

先开始以为先前的括号序列表示出的 ((x,y)) 为新的 ((0,0)),到 ((frac{n}{2},frac{n}{2})) 的矩阵是一个矩形((frac{n}{2}) 是左括号的个数,右括号的个数),画了画好像并不是。(尴尬

( ext{Solution})

首先可以特判 (n) 为奇,(x>frac{n}{2})(y>frac{n}{2}),给出括号序列不合法的情况。

然后考虑从 ((x,y))((frac{n}{2},frac{n}{2}))。(横坐标是左括号个数,纵坐标是右括号个数)

我们将上面的小矩形翻一下:

首先,设 ((r,l)) 为第一个越过黄线的坐标,那么显然 (l=r+1)。左括号还有 (frac{n}{2}-y-r) 个,右括号还有 (frac{n}{2}-x-l) 个。我们接下来设向上为左括号,向右为右括号,那向右总共走了 (frac{n}{2}-x-l+r=frac{n}{2}-x-1),向上总共走了 (frac{n}{2}-y-r+l=frac{n}{2}-y+1)

推到这里,我们发现越过黄线的点的向上,向右的步数是不变的,也即越过黄线的点一定会到坐标 ((frac{n}{2}-x-1,frac{n}{2}-y+1))

那么答案就是:( ext C(frac{n}{2}-x+frac{n}{2}-y,frac{n}{2}-x)- ext C(frac{n}{2}-x+frac{n}{2}-y,frac{n}{2}-x-1))

有点绕,不懂或有误的欢迎来探讨哟!

( ext{Code})

#include <cstdio>

#define rep(i,_l,_r) for(register signed i=(_l),_end=(_r);i<=_end;++i)
#define fep(i,_l,_r) for(register signed i=(_l),_end=(_r);i>=_end;--i)
#define erep(i,u) for(signed i=head[u],v=to[i];i;i=nxt[i],v=to[i])
#define efep(i,u) for(signed i=Head[u],v=to[i];i;i=nxt[i],v=to[i])
#define print(x,y) write(x),putchar(y)

template <class T> inline T read(const T sample) {
    T x=0; int f=1; char s;
    while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
    while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
    return x*f;
}
template <class T> inline void write(const T x) {
    if(x<0) return (void) (putchar('-'),write(-x));
    if(x>9) write(x/10);
    putchar(x%10^48);
}
template <class T> inline T Max(const T x,const T y) {if(x>y) return x; return y;}
template <class T> inline T Min(const T x,const T y) {if(x<y) return x; return y;}
template <class T> inline T fab(const T x) {return x>0?x:-x;}
template <class T> inline T gcd(const T x,const T y) {return y?gcd(y,x%y):x;}
template <class T> inline T lcm(const T x,const T y) {return x/gcd(x,y)*y;}
template <class T> inline T Swap(T &x,T &y) {x^=y^=x^=y;}

#include <cstring>

const int maxn=2e6+5,mod=1e9+7;

int n,fac[maxn],ifac[maxn];
char s[maxn];

int qkpow(int x,int y) {
	int r=1;
	while(y) {
		if(y&1) r=1ll*r*x%mod;
		x=1ll*x*x%mod; y>>=1;
	}
	return r;
}

void init() {
	fac[0]=1;
	rep(i,1,maxn-5) fac[i]=1ll*fac[i-1]*i%mod;
	ifac[maxn-5]=qkpow(fac[maxn-5],mod-2);
	fep(i,maxn-6,0) ifac[i]=1ll*ifac[i+1]*(i+1)%mod;
}

int C(int n,int m) {
	return 1ll*fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}

int main() {
	int l,r; bool flag;
	init();
	while(~scanf("%d",&n)) {
		scanf("%s",s); l=r=flag=0;
		rep(i,0,strlen(s)-1) {
			if(s[i]=='(') ++l;
			else ++r;
			if(l<r) flag=1;
		}
		if(n&1) {puts("0"); continue;}
		n>>=1;
		if(flag||l>n||r>n) {puts("0"); continue;}
		l=n-l; r=n-r;
		print((C(l+r,l)-C(l+r,r+1)+mod)%mod,'
');
	}
	return 0;
} 
原文地址:https://www.cnblogs.com/AWhiteWall/p/13629399.html