分析:
記路徑長度為n
n,那麼機械人最多向右走\lfloor \frac \rfloor⌊
2n
⌋步並向左走\lfloor \frac \rfloor⌊
2n
⌋步。
ans(n) = \sum_^ \rfloor} c_n^ \ catalan(i)an
s(n)
=∑i
=0⌊
2
n⌋
c
n2i
ca
tala
n(i)
其中catalan(n)ca
tala
n(n)
表示第n
n個卡特蘭數。
卡特蘭數定義:catalan(n)=\frac^n}ca
tala
n(n)
=n+
1c
2n
n
遞推公式catalan(n)=\frac\ catalan(n-1)ca
tala
n(n)
=n+
14
n−2
cat
alan
(n−1
) 基於nn
的取值範圍,此題可以預處理出1,000,0011,
000,
001以內的乘法逆元、卡特蘭數。
每次詢問,都可以遞推組合數,或者提前一次性預處理好階乘和階乘的逆元得到組合數;累加組合數與相應卡特蘭數的乘積,得到答案。
事實上,ans(n)an
s(n)
是第nn
個默慈金數,還有更高效的遞推公式:
m_=m_n+ \sum_^m_i m = \frac}m
n+1
=m
n+
∑i=
0n−
1m
i
mn−1
−i=
n+3
(2n
+3)m
n
+3nm
n−1
。需要注意的是:
cc[ n] 位 n ! 的 對(1e9 + 7)的逆元,能預處理的都預處理成陣列,要不然使用多次會超時。
求逆元o(1)的方法
#include #include #include #include using namespace std;
typedef long long ll;
typedef long long ll;
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define rep1(i,x,y) for(int i =(int)x;i<=(int)y;i++)
const int mod = 1e9 + 7;
const int n = 1e6 + 100;
int inv[n];
int inv(int x)
ll cat[n] , d[n], f[n] ,cc[n];
void init()
for(int i = 3 ; i= mod)
ans %= mod;
}printf("%d\n",(int)ans);
}return 0;
}
catalan數的應用 變形 HDU1133
檢視維基百科,對卡特蘭數公式證明是這樣的 令1表示進棧,0表示出棧,則可轉化為求乙個2n位 含n個1 n個0的二進位制數,滿足從左往右掃瞄到任意一位時,經過的0數不多於1數。顯然含n個1 n個0的2n位二進位制數共有 考慮乙個含n個1 n個0的2n位二進位制數,掃瞄到第2m 1位上時有m 1個0和m...
Catalan數(卡特蘭數)
卡特蘭數 規定h 0 1,而h 1 1,h 2 2,h 3 5,h 4 14,h 5 42,h 6 132,h 7 429,h 8 1430,h 9 4862,h 10 16796,h 11 58786,h 12 208012,h 13 742900,h 14 2674440,h 15 969484...
卡特蘭數 Catalan數
卡特蘭數 規定h 0 1,而h 1 1,h 2 2,h 3 5,h 4 14,h 5 42,h 6 132,h 7 429,h 8 1430,h 9 4862,h 10 16796,h 11 58786,h 12 208012,h 13 742900,h 14 2674440,h 15 969484...