WD与循环 组合数学
生活随笔
收集整理的這篇文章主要介紹了
WD与循环 组合数学
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
WD與循環
LG傳送門
為什么大家都是先算\(n\)個數的和等于\(m\)的情況再求前綴和?
既然已經想到了插板法,為什么不直接對\(n\)個數的和\(\le m\)的情況做呢?
基本套路沒有變:考慮對于\(n\)個非負整數,先變成\(n\)個正整數,求和\(\le m + n\)的情況。下面是不同的地方:在\(m + n\)個小球之間插入\(n\)塊板子,具體地說,在每個球的右邊可以插入一塊板子,對于從左往右數第\(i\)塊板子,它到第\(i - 1\)塊板子或者左端點之間的小球數就是第\(i\)個數,對于最右邊的一塊板子,它左邊的板子數即沒有被分到任何一個數中的小球個數一定\(\ge 0\),這正好對應了我們\(\le m + n\)的條件。得到式子\(\binom {n + m} {n}\),lucas定理即可。
yyb是我們的紅太陽,%yyb有益身心健康
//written by newbiechd #include <cstdio> #include <cctype> #define R register #define I inline #define B 1000000 #define L long long using namespace std; const int yyb = 19491001; char buf[B], *p1, *p2; I char gc() { return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, B, stdin), p1 == p2) ? EOF : *p1++; } I L rd() {L f = 0;R char c = gc();while (c < 48 || c > 57)c = gc();while (c > 47 && c < 58)f = f * 10 + (c ^ 48), c = gc();return f; } L a[yyb]; I L pow(L x, L y) {L r = 1;for (x %= yyb; y; y >>= 1, x = x * x % yyb)if (y & 1)r = r * x % yyb;return r; } I L com(L n, L m) {if (m > n)return 0;return a[n] * pow(a[m], yyb - 2) % yyb * pow(a[n - m], yyb - 2) % yyb; } L lucas(L n, L m) {if (!m)return 1;return com(n % yyb, m % yyb) * lucas(n / yyb, m / yyb) % yyb; } int main() {R int T = rd(), i;L n, m;a[0] = 1;for (i = 1; i < yyb; ++i)a[i] = a[i - 1] * i % yyb;for (i = 1; i <= T; ++i)n = rd(), m = rd(), printf("%lld\n", lucas(n + m, n));return 0; }轉載于:https://www.cnblogs.com/cj-chd/p/10448339.html
總結
以上是生活随笔為你收集整理的WD与循环 组合数学的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php一些高级函数方法
- 下一篇: 控制情绪,不被左右