1
+ #include < bits/stdc++.h>
2
+ #include " fexp.cpp" // LATEX_IGNORED_LINE
3
+ #define ll long long
4
+ using namespace std ;
5
+
6
+ struct Combin {
7
+ vector<ll> fat, finv;
8
+ Combin (int n){
9
+ fat.assign (n+1 , 1 );
10
+ for (int i=2 ; i<=n; i++) fat[i] = fat[i-1 ]*i % mod;
11
+ finv.assign (n+1 , fexp (fat.back (), mod-2 ));
12
+ for (int i=n; i>0 ; i--) finv[i-1 ] = finv[i]*i % mod;
13
+ }
14
+ ll choose (ll n, ll k){ assert (n < fat.size ()); return k>n||k<0 ? 0 : fat[n] * finv[k] % mod * finv[n-k] % mod; } // precalc O(N)
15
+ ll chooseLinear (ll n, ll k){ // O(k) || min(k, n-k);
16
+ k = min (k, n-k);
17
+ ll ans = 1 , inv=1 ;
18
+ for (int i=n; i>k; i--) ans = ans*i % mod;
19
+ for (int i=1 ; i<=n-k; i++) inv = inv*i % mod;
20
+ return ans * fexp (inv, mod-2 ) % mod;
21
+ }
22
+ ll permRepetition (const vector<int > &cnt){
23
+ ll n = accumulate (begin (cnt), end (cnt), 0ll ), ans = fat[n];
24
+ for (int x : cnt) ans = ans * finv[x] % mod;
25
+ return ans;
26
+ }
27
+ ll sumNci (ll n){ return fexp (2 , n); } // for(i=0; i<=n) sum+=choose(n, i);
28
+ ll sumicK (ll n, ll k){ return choose (n+1 , k+1 ); } // for(i=0; i<=n) sum+=choose(i, k);
29
+ ll sumNKcK (ll n, ll k){ return choose (n+k+1 , k); } // for(i=0; i<=k) sum+=choose(n+i, i);
30
+ ll sumNsqr (ll n){ return choose (n+n, n); } // for(i=0; i<=n) sum += pow(choose(n, i), 2);
31
+ ll catalan (ll n){ return choose (2 *n, n) * fexp (n+1 , mod-2 ) % mod; }
32
+ // Stars and Bars
33
+ ll starsBars (ll n, ll k){ return choose (n+k-1 , n); } // O(choose)
34
+ ll starsLowerBound (ll n, const vector<ll> &lw){ // O(k)
35
+ for (auto x : lw) n -= x;
36
+ return starsBars (n, lw.size ());
37
+ }
38
+ ll starsUpperBound (ll n, ll k, ll up){ // O(k)
39
+ ll ans = 0 ;
40
+ for (int i=0 ; i<=k; i++)
41
+ ans += choose (k, i) * choose (n+k-1 -(up+1 )*i, k-1 ) % mod * (i&1 ? -1 :+1 );
42
+ return ans;
43
+ }
44
+ ll starsUpperBound (ll M, const vector<ll> &up){ // O(N*M)
45
+ int N = up.size ();
46
+ vector dp (up.size ()+1 , vector<ll>(N+1 ));
47
+ for (int m=0 ; m<=M; m++) dp[0 ][m] = choose (N+m-1 , m);
48
+ for (int n=1 ; n<=N; n++)
49
+ for (int m=0 ; m<=M; m++)
50
+ dp[n][m] = dp[n-1 ][m] - (m-up[n-1 ]-1 < 0 ? 0 : dp[n-1 ][m-up[n-1 ]-1 ]);
51
+ return dp[N][M];
52
+ }
53
+ ll starsLowerUpperBound (ll n, const vector<ll> &lw, const vector<ll> &up){ // O(N*M)
54
+ for (auto x : lw) n -= x;
55
+ return starsUpperBound (n, up);
56
+ }
57
+ };
58
+
59
+ const int MAXN = 5e3 ;
60
+ ll pascal[MAXN][MAXN];
61
+ // pascal[n][k] = choose(n, k);
62
+
63
+ void Pascal (int N){
64
+ pascal[0 ][0 ] = 1 ;
65
+ for (int n=1 ; n<=N; n++){
66
+ pascal[n][0 ] = pascal[n][n] = 1 ;
67
+ for (int k=1 ; k<n; k++)
68
+ pascal[n][k] = (pascal[n-1 ][k-1 ] + pascal[n-1 ][k]) % mod;
69
+ }
70
+ }
71
+
72
+ // LATEX_IGNORED_BEGIN pra testar as funções
73
+ int main (){
74
+ int N = 10 ;
75
+ Pascal (N);
76
+
77
+ for (int n=0 ; n<=N; cout << endl, n++)
78
+ for (int k=0 ; k<=n; k++)
79
+ cout << pascal[n][k] << " \t " ;
80
+ cout << endl;
81
+
82
+ Combin cb (N);
83
+
84
+ for (int n=0 ; n<=N; cout << endl, n++)
85
+ for (int k=0 ; k<=n; k++)
86
+ cout << cb.choose (n, k) << " \t " ;
87
+ cout << endl;
88
+
89
+ for (int n=0 ; n<=N; cout << endl, n++)
90
+ for (int k=0 ; k<=n; k++)
91
+ cout << cb.chooseLinear (n, k) << " \t " ;
92
+ cout << endl;
93
+
94
+ for (int n=0 ; n<=N; n++) cout << cb.fat [n] << " \t " ;
95
+ cout << endl;
96
+ for (int n=0 ; n<=N; n++) cout << n << " \t " ;
97
+ cout << endl;
98
+ for (int n=0 ; n<=N; n++) cout << cb.finv [n] << " " ;
99
+ cout << endl;
100
+ }
101
+ // LATEX_IGNORED_END
0 commit comments