洛谷 P1641 SCOI2010 生成字串

2021-08-29 01:57:01 字數 2269 閱讀 5996

洛谷 p1641 [scoi2010]生成字串

題目描述

lxhgww最近接到了乙個生成字串的任務,任務需要他把n個1和m個0組成字串,但是任務還要求在組成的字串中,在任意的前k個字元中,1的個數不能少於0的個數。現在lxhgww想要知道滿足要求的字串共有多少個,聰明的程式設計師們,你們能幫助他嗎?

輸入格式:

輸入資料是一行,包括2個數字n和m

輸出格式:

輸出資料是一行,包括1個數字,表示滿足要求的字串數目,這個數可能會很大,只需輸出這個數除以20100403的餘數。

輸入輸出樣例輸入

輸出2 2

29 7

3432

說明題目標籤:組合數學 逆元

聽說這好像時一道高考題orz

用n代表1的個數,m代表0的個數,設 x=n+m,y=n-m,建立直角座標系,生成字串就可以用從(0,0)到(n+m,n-m)的上公升n次下降m次的折線表示,所有的情況個數為c(n+m,m)。

要滿足任意的前k個字元中,1的個數大於等於0的個數,也就是影象要始終在x軸的上方(n-m>=0)

如果影象到了x軸下方則存在k=n+m,n-m<0,1的個數小於0的個數

直接求影象在x軸上方的所有情況個數有點困難,根據對稱性可以轉化一下

影象有在x軸下方的情況可以看作折線到達y=-1

將影象到達y=-1之前的影象關於直線y=-1對稱翻摺可以得到

從(0,0)到達y=-1,下降的次數比上公升的次數多一次,翻摺後,可以看成從(0,-2)到y=-1,上公升的次數比下降的次數多一次,這樣,所有存在n-m小於0的情況數等於從(0,-2)上公升n+1次下降m-1次的折線圖像的所有情況個數:c(n+m,m-1)。

所以答案就為c(n+m,m)-c(n+m,m-1)

然後就是處理組合數的問題了,這個資料範圍,用楊輝三角打表不現實,只能逆元打表了,之後用公式求組合數

在模質數m下,求1~n的逆元(n板子:

const int maxn = 1e6+5;

int inv[maxn];

void inverse(int n,int m)

}

推導過程:

由 (m/i) * i + m%i = 0 (mod m)

=> -(m/i) * i = m%i (mod m) 兩邊同時除以 (m%i )*i

=> -(m/i) * (1/(m%i)) = 1/(i) (mod m)

即:-(m/i) * inv[m%i] = inv[i] (mod m)

所以:inv[i]=(m-m/i) * inv[m%i]%m

**:

#include

#define ll long long

using

namespace std;

const ll m =

20100403

;const

int n =

1e6+10;

int inv[n]

,fac[n]

,n,m;

void

init

(int n)

inv[1]

=1;for

(int i=

2;i<=n;i++

)for

(int i=

2;i<=n;i++)}

intcomb

(int a,

int b)

intmain()

int an=

(comb

(m+n,m)

-comb

(m+n,m-1)

)%m;

cout<

return0;

}

洛谷 P1641 SCOI2010 生成字串

題目描述 lxhgww最近接到了乙個生成字串的任務,任務需要他把n個1和m個0組成字串,但是任務還要求在組成的字串中,在任意的前k個字元中,1的個數不能少於0的個數。現在lxhgww想要知道滿足要求的字串共有多少個,聰明的程式設計師們,你們能幫助他嗎?輸入格式 輸入資料是一行,包括2個數字n和m 輸...

洛谷 P1641 SCOI2010 生成字串

洛谷 這題一看就是卡塔蘭數。因為 cnt 1 leq cnt 0 很顯然的卡塔蘭嘛!平時我們推導卡塔蘭是用乙個邊長為n的正方形推的,相當於從 0,0 點走到 n,n 點,向上走的步數不能超過向右走,求出的方案數就是卡塔蘭數。即總方案 不合法方案 frac 這題只是改成了從 0,0 走到 n,m 點,...

P1641 SCOI2010 生成字串

lxhgww最近接到了乙個生成字串的任務,任務需要他把n個1和m個0組成字串,但是任務還要求在組成的字串中,在任意的前k個字元中,1的個數不能少於0的個數。現在lxhgww想要知道滿足要求的字串共有多少個,聰明的程式設計師們,你們能幫助他嗎?輸入資料是一行,包括2個數字n和m 輸出資料是一行,包括1...