├── .gitignore ├── 2SAT └── 2SAT.cpp ├── Berlekamp Massey ├── berlekamp_massey_fft.cpp └── koosaga_berlekamp_massey.cpp ├── CONTRIBUTING.md ├── Centroid Decomposition ├── centroid_basic.cpp └── centroid_decomposition.cpp ├── Convex Hull └── graham_scan_convex_hull.cpp ├── Delaunay Triangulation └── delaunay.cpp ├── Disjoint Set Union (DSU) └── dsu.cpp ├── Euler Totient Function └── etf.cpp ├── FFT ├── fft_big_mod.cpp └── fft_float.cpp ├── Fast Sieve └── fast_sieve.cpp ├── Fibonacci └── fast_doubling.cpp ├── Heavy Light Decomposition └── HLD.cpp ├── Implicit Segment Tree └── implicit_segment_tree.cpp ├── Li Chao Tree └── li_chao_tree.py ├── Longest Increasing Subsequence ├── LIS.cpp └── lis.py ├── Manacher's algorithm └── manacher.cpp ├── Matrix └── matrix.cpp ├── Max Flow ├── dinic.cpp ├── maxflow.ml ├── maxflow_topcoder.cpp └── mcmf_with_dual.cpp ├── Misc └── order_of_prime_in_factorial.py ├── Mo └── even_odd_mo.cpp ├── Order Statistic Tree └── ost.cpp ├── Palindromic Tree ├── pal_tree_template.cpp └── palindromic_tree.cpp ├── Persistent Segment Tree ├── chemthan_pst.cpp └── persistent_segtree.cpp ├── Polynomial ├── Polynomial.cpp └── adamant_poly.hpp ├── Prime Factorization └── py_prime_factorization.py ├── README.md ├── Rabin Miller Primality Test └── rabin_miller.cpp ├── Range Max in Window └── rmq_fixed_window.cpp ├── ReedsSloane ├── koosaga_reedssloane.cpp └── zimpha_linear_recurrence.cpp ├── Segment Tree ├── MergeMethodAsTemplateArg.cpp ├── segment_tree.cpp └── segtree_template.cpp ├── Sieve of Eratosthenes └── sieve.cpp ├── Sparse Table └── sparse_table.cpp ├── Suffix Array Construction ├── nlog2n.cpp └── nlogn.cpp ├── Suffix Automaton └── suffix_automaton.cpp ├── TODO.md ├── Trie └── iterative_trie.cpp ├── Wavelet Tree └── wavelet_tree.cpp ├── Xor Gauss └── XorGauss.cpp ├── binary_search_utils └── bs_utils.py └── fast_mod_mul_barrett_reduction └── barrett_reduction.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | -------------------------------------------------------------------------------- /2SAT/2SAT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define pos(v) ((v) << 1) 5 | #define neg(v) (pos(v) ^ 1) 6 | struct Twosat { 7 | static const int MAXV = 2e5 + 5; 8 | int n; 9 | vector forward[MAXV], backward[MAXV]; 10 | bool used[MAXV]; 11 | int cnt, order[MAXV], comp[MAXV]; 12 | void init(int _n) { 13 | n = _n; 14 | for (int i = 0; i < n; i++) { 15 | forward[i].clear(); 16 | backward[i].clear(); 17 | } 18 | } 19 | void add(int u, int v) { 20 | forward[u].push_back(v); 21 | backward[v].push_back(u); 22 | } 23 | void dfs1(int u) { 24 | used[u] = true; 25 | for (int i = 0; i < forward[u].size(); i++) { 26 | int v = forward[u][i]; 27 | if (!used[v]) dfs1(v); 28 | } 29 | order[cnt++] = u; 30 | } 31 | void dfs2(int u, int c) { 32 | comp[u] = c; 33 | for (int i = 0; i < backward[u].size(); i++) { 34 | int v = backward[u][i]; 35 | if (comp[v] == -1) dfs2(v, c); 36 | } 37 | } 38 | int solve(vector& res) { 39 | cnt = 0; 40 | memset(used, 0, sizeof(used)); 41 | for (int u = 0; u < n; u++) if (!used[u]) dfs1(u); 42 | memset(comp, -1, sizeof(comp)); 43 | int c = 0; 44 | for (int i = n - 1; i >= 0; i--) { 45 | int u = order[i]; 46 | if (comp[u] == -1) dfs2(u, c++); 47 | } 48 | for (int u = 0; u < n; u += 2) 49 | if (comp[u] == comp[u ^ 1]) return 0; 50 | res.clear(); 51 | for (int u = 0; u < n; u += 2) { 52 | int choose = (comp[u] > comp[u ^ 1]) ? u : u ^ 1; 53 | if (!(choose & 1)) res.push_back(choose >> 1); 54 | } 55 | return 1; 56 | } 57 | } twosat; 58 | 59 | int main() { 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /Berlekamp Massey/berlekamp_massey_fft.cpp: -------------------------------------------------------------------------------- 1 | struct berlekamp-massey { 2 | struct poly { std::vector a; poly() { a.clear(); } 3 | poly (std::vector &a) : a (a) {} 4 | int length () const { return a.size(); } 5 | poly move (int d) { std::vector na (d, 0); 6 | na.insert (na.end (), a.begin (), a.end ()); 7 | return poly (na); } 8 | int calc(std::vector &d, int pos) { int ret = 0; 9 | for (int i = 0; i < (int) a.size (); ++i) { 10 | if ((ret += 1LL * d[pos - i] * a[i] % MOD) >= MOD) { 11 | ret -= MOD; } } 12 | return ret; } 13 | poly operator - (const poly &b) { 14 | std::vector na (std::max (this -> length (), b.length ())); 15 | for (int i = 0; i < (int) na.size (); ++i) { 16 | int aa = i < this -> length () ? this -> a[i] : 0, 17 | bb = i < b.length () ? b.a[i] : 0; 18 | na[i] = (aa + MOD - bb) % MOD; } 19 | return poly (na); } }; 20 | poly operator * (const int &c, const poly &p) { 21 | std::vector na (p.length ()); 22 | for (int i = 0; i < (int) na.size (); ++i) { 23 | na[i] = 1LL * c * p.a[i] % MOD; } 24 | return na; } 25 | std::vector solve(vector a) { 26 | int n = a.size (); poly s, b; 27 | s.a.push_back (1), b.a.push_back (1); 28 | for (int i = 0, j = -1, ld = 1; i < n; ++i) { 29 | int d = s.calc(a, i); if (d) { 30 | if ((s.length () - 1) * 2 <= i) { 31 | poly ob = b; b = s; 32 | s = s - 1LL * d * inverse (ld) % MOD * ob.move (i - j); 33 | j = i; ld = d; 34 | } else { 35 | s = s - 1LL * d * inverse (ld) % MOD * b.move (i - j); } } } 36 | return s.a; } }; 37 | -------------------------------------------------------------------------------- /Berlekamp Massey/koosaga_berlekamp_massey.cpp: -------------------------------------------------------------------------------- 1 | // https://codeforces.com/contest/506/submission/45057436 2 | #include 3 | using namespace std; 4 | using pi = pair; 5 | using lint = long long; 6 | const int mod = 1e4 + 7; 7 | 8 | lint ipow(lint x, lint p){ 9 | lint ret = 1, piv = x; 10 | while(p){ 11 | if(p & 1) ret = ret * piv % mod; 12 | piv = piv * piv % mod; 13 | p >>= 1; 14 | } 15 | return ret; 16 | } 17 | 18 | namespace linear_seq { 19 | vector berlekamp_massey(vector x){ 20 | vector ls, cur; 21 | int lf, ld; 22 | for(int i=0; i c(i-lf-1); 36 | c.push_back(k); 37 | for(auto &j : ls) c.push_back(-j * k % mod); 38 | if(c.size() < cur.size()) c.resize(cur.size()); 39 | for(int j=0; j=(int)cur.size()){ 43 | tie(ls, lf, ld) = make_tuple(cur, i, (t - x[i]) % mod); 44 | } 45 | cur = c; 46 | } 47 | for(auto &i : cur) i = (i % mod + mod) % mod; 48 | return cur; 49 | } 50 | int get_nth(vector rec, vector dp, lint n){ 51 | int m = rec.size(); 52 | vector s(m), t(m); 53 | s[0] = 1; 54 | if(m != 1) t[1] = 1; 55 | else t[0] = rec[0]; 56 | auto mul = [&rec](vector v, vector w){ 57 | int m = v.size(); 58 | vector t(2 * m); 59 | for(int j=0; j=m; j--){ 66 | for(int k=1; k<=m; k++){ 67 | t[j-k] += 1ll * t[j] * rec[k-1] % mod; 68 | t[j-k] %= mod; 69 | } 70 | } 71 | t.resize(m); 72 | return t; 73 | }; 74 | while(n){ 75 | if(n & 1) s = mul(s, t); 76 | t = mul(t, t); 77 | n >>= 1; 78 | } 79 | lint ret = 0; 80 | for(int i=0; i x, lint n){ 84 | if(n < x.size()) return x[n]; 85 | vector v = berlekamp_massey(x); 86 | if(v.empty()) return 0; 87 | return get_nth(v, x, n); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Guidelines for contributing to this project 2 | 3 | - Structure 4 | - Each new algorithm should go into a new directory and should contain the following files: 5 | - `.cpp`: Template for the algorithm 6 | - `example.cpp`: Usage of the algorithm to get a problem accepted on Codeforces/Codechef 7 | - `README.md`: List of URLs to related problems 8 | - Merging changes to master 9 | - Clone this repo 10 | - Create a new branch on the cloned repo with the name `` 11 | - Commit changes to that branch 12 | - Create a Pull Request from that branch to the master branch of this repo. 13 | -------------------------------------------------------------------------------- /Centroid Decomposition/centroid_basic.cpp: -------------------------------------------------------------------------------- 1 | // http://codeforces.com/contest/321/submission/12154727 2 | #include 3 | 4 | using namespace std; 5 | 6 | typedef pair II; 7 | typedef vector< II > VII; 8 | typedef vector VI; 9 | typedef vector< VI > VVI; 10 | typedef long long int LL; 11 | typedef unsigned long long int ULL; 12 | 13 | #define PB push_back 14 | #define MP make_pair 15 | #define F first 16 | #define S second 17 | #define SZ(a) (int)(a.size()) 18 | #define ALL(a) a.begin(),a.end() 19 | #define SET(a,b) memset(a,b,sizeof(a)) 20 | #define LET(x,a) __typeof(a) x(a) 21 | 22 | #define rep(i, begin, end) for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end))) 23 | //Works for forward as well as backward iteration 24 | 25 | #define gu getchar 26 | #define pu putchar 27 | #define si(n) scanf("%d",&n) 28 | #define dout(n) printf("%d\n",n) 29 | #define sll(n) scanf("%lld",&n) 30 | #define lldout(n) printf("%lld\n",n) 31 | 32 | #define DRT() int t; si(t); while(t--) 33 | 34 | #define PlUSWRAP(index,n) index = (index+1)%n //index++; if(index>=n) index=0 35 | #define MINUSWRAP(index,n) index = (index + n -1)%n //index--; if(index<0) index=n-1 36 | #define ROUNDOFFINT(d) d = (int)((double)d + 0.5) //Round off d to nearest integer 37 | 38 | #define FLUSHN while(gu()!='\n') 39 | #define FLUSHS while(gu()!=' ') 40 | 41 | #define TRACE 42 | 43 | #ifdef TRACE 44 | #define trace1(x) cerr << #x << ": " << x << endl; 45 | #define trace2(x, y) cerr << #x << ": " << x << " | " << #y << ": " << y << endl; 46 | #define trace3(x, y, z) cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl; 47 | #define trace4(a, b, c, d) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl; 48 | #define trace5(a, b, c, d, e) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl; 49 | #define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl; 50 | 51 | #else 52 | 53 | #define trace1(x) 54 | #define trace2(x, y) 55 | #define trace3(x, y, z) 56 | #define trace4(a, b, c, d) 57 | #define trace5(a, b, c, d, e) 58 | #define trace6(a, b, c, d, e, f) 59 | 60 | #endif 61 | 62 | //FILE *fin = freopen("in","r",stdin); 63 | //FILE *fout = freopen("out","w",stdout); 64 | const int N = int(1e5)+10; 65 | const int LOGN = 20; 66 | set g[N]; 67 | int sub[N]; 68 | char ans[N]; 69 | int n; 70 | /*Using centroid Decomposition of a tree */ 71 | 72 | /*-----------------Decomposition Part--------------------------*/ 73 | int nn; 74 | void dfs1(int u,int p) 75 | { 76 | sub[u]=1; 77 | nn++; 78 | for(auto it=g[u].begin();it!=g[u].end();it++) 79 | if(*it!=p) 80 | { 81 | dfs1(*it,u); 82 | sub[u]+=sub[*it]; 83 | } 84 | } 85 | int dfs2(int u,int p) 86 | { 87 | for(auto it=g[u].begin();it!=g[u].end();it++) 88 | if(*it!=p && sub[*it]>nn/2) 89 | return dfs2(*it,u); 90 | return u; 91 | } 92 | void decompose(int root,int p,char C) 93 | { 94 | nn=0; 95 | dfs1(root,root); 96 | int centroid = dfs2(root,root); 97 | if(p==-1)p=centroid; 98 | ans[centroid] = C; 99 | for(auto it=g[centroid].begin();it!=g[centroid].end();it++) 100 | { 101 | g[*it].erase(centroid); 102 | decompose(*it,centroid,C+1); 103 | } 104 | g[centroid].clear(); 105 | } 106 | int main() 107 | { 108 | si(n); 109 | for(int i=0;i 5 | using namespace std; 6 | 7 | #define MAXN 100013 8 | int N; 9 | vector adj[MAXN]; 10 | 11 | namespace cd { 12 | int sz[MAXN]; 13 | int cpar[MAXN]; 14 | bool vis[MAXN]; 15 | 16 | void dfs(int n, int p=-1) { 17 | sz[n] = 1; 18 | for (int v : adj[n]) if (v != p && !vis[v]) { 19 | dfs(v, n); 20 | sz[n] += sz[v]; 21 | } 22 | } 23 | 24 | int centroid(int n) { 25 | dfs(n); 26 | int num = sz[n]; 27 | int p = -1; 28 | do { 29 | int nxt = -1; 30 | for (int v : adj[n]) if (v != p && !vis[v]) { 31 | if (2 * sz[v] > num) 32 | nxt = v; 33 | } 34 | p = n, n = nxt; 35 | } while (~n); 36 | return p; 37 | } 38 | 39 | void centroid_decomp(int n=0, int p=-1) { 40 | int c = centroid(n); 41 | vis[c] = true; 42 | cpar[c] = p; 43 | for (int v : adj[c]) if (!vis[v]) { 44 | centroid_decomp(v, c); 45 | } 46 | } 47 | } 48 | 49 | using cd::centroid_decomp; 50 | using cd::cpar; 51 | 52 | int main() { 53 | N = 5; 54 | vector > edges = {{0, 1}, {1, 2}, {1, 3}, {3, 4}}; 55 | for (auto p : edges) { 56 | adj[p.first].push_back(p.second); 57 | adj[p.second].push_back(p.first); 58 | } 59 | 60 | centroid_decomp(); 61 | 62 | for (int i = 0; i < N; i++) 63 | cout << i << " -> " << cpar[i] << endl; 64 | } 65 | -------------------------------------------------------------------------------- /Convex Hull/graham_scan_convex_hull.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define linf (long long)1e18 5 | #define inf (int)1e9 6 | #define forall(i,a,b) for(int i=a;i=b;i--) 10 | #define foreach(v, c) for(typeof( (c).begin()) v = (c).begin(); v != (c).end(); ++v) 11 | #define all(a) a.begin(), a.end() 12 | #define in(a,b) ((b).find(a) != (b).end()) 13 | #define pb push_back 14 | #define fill(a,v) memset(a, v, sizeof (a)) 15 | #define sz(a) ((int)(a.size())) 16 | #define mp make_pair 17 | #define ll long long 18 | 19 | ll maxe(ll a,ll b) {if(a>b)return a;else return b;} 20 | ll mine(ll a,ll b) {if(a0)return a;return (-a);} 22 | 23 | // comparision Guys 24 | #define DREP_sort(a) sort(all(a)); a.erase(unique(all(a)),a.end()) //deletes repeat sorted 25 | #define DREP(a) a.erase(unique(all(a)),a.end()) //deletes repeat 26 | 27 | // The bit standard guys 28 | #define bit(x,i) (x&(1< vi; 37 | typedef vector vvi; 38 | typedef pair pi; 39 | typedef maphash; 40 | #define ft first 41 | #define sd second 42 | 43 | 44 | // the data types 45 | #define st string 46 | #define ch char 47 | 48 | /* 49 | This is the graham scan for the convex hull. 50 | Step 1 Find the least point in plane in terms of y and then x in case of equality use 51 | USE-the bool operator less than comparator that is use to compare the current element with 52 | element B 53 | 54 | Step 2 That above point is a pivot so sort all the angles wrt that point 55 | you don't have to acutally find the angles you just compare which one of the angles is 56 | greater than the other one so we can compare between a and b to find which 57 | makes a greater tan with pivot 58 | USE Polar order and conterclockwise checker 59 | 60 | Step 3 REmove unnecessary vertices and make the hull 61 | 62 | 63 | */ 64 | 65 | class Point { 66 | public: 67 | int x, y; 68 | bool operator < (Point b) 69 | {if (y != b.y)return y < b.y; else return x < b.x;} 70 | }; 71 | Point pivot; 72 | 73 | // returns -1 if a -> b -> c forms a counter-clockwise turn, 74 | // +1 for a clockwise turn, 0 if they are collinear 75 | // The comparision is simple compares point a with b and c angles 76 | // if angle by b,a is less than ca then you have counterclockwise 77 | int ccw(Point a, Point b, Point c) { 78 | int area = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); 79 | if (area > 0)return -1; 80 | else if (area < 0)return 1; 81 | return 0; 82 | } 83 | 84 | // returns square of Euclidean distance between two points 85 | int sqrDist(Point a, Point b) { 86 | int dx = a.x - b.x, dy = a.y - b.y;return dx * dx + dy * dy; 87 | } 88 | 89 | // used for sorting points according to polar order w.r.t the pivot 90 | bool POLAR_ORDER(Point a, Point b) { 91 | int order = ccw(pivot, a, b); 92 | if (order == 0)return sqrDist(pivot, a) < sqrDist(pivot, b); 93 | return (order == -1); 94 | } 95 | 96 | stack grahamScan(Point *points, int N) { 97 | stack hull; // this is a stack of struct of points 98 | 99 | if (N < 3)return hull; 100 | 101 | // find the point having the least y coordinate (pivot), 102 | // ties are broken in favor of lower x coordinate 103 | 104 | int leastY = 0; 105 | for (int i = 1; i < N; i++)if (points[i] < points[leastY])leastY = i; 106 | // swap the pivot with the first point 107 | Point temp = points[0];points[0] = points[leastY];points[leastY] = temp; 108 | // sort the remaining point according to polar order about the pivot 109 | pivot = points[0]; 110 | sort(points + 1, points + N, POLAR_ORDER); 111 | 112 | forall(i,0,N)cout << points[i].x << " " << points[i].y <<"\n"; 113 | 114 | hull.push(points[0]); 115 | hull.push(points[1]); 116 | hull.push(points[2]); 117 | 118 | for (int i = 3; i < N; i++) { 119 | Point top = hull.top(); 120 | hull.pop(); 121 | while (ccw(hull.top(), top, points[i]) != -1) { 122 | top = hull.top(); 123 | hull.pop(); 124 | } 125 | hull.push(top); 126 | hull.push(points[i]); 127 | } 128 | return hull; 129 | } 130 | 131 | 132 | //their is however a special case of three points in a line 133 | int main() { 134 | Point points[] = {{0, 10}, {10, 10}, {10, 0}, {0,0},{5,5},{6,6},{7,7}, {6,7}}; 135 | int N = sizeof(points)/sizeof(points[0]); 136 | 137 | stack hull = grahamScan(points, N); 138 | while (!hull.empty()) { 139 | Point p = hull.top(); 140 | hull.pop(); 141 | 142 | printf("(%d, %d)\n", p.x, p.y); 143 | } 144 | 145 | return 0; 146 | } -------------------------------------------------------------------------------- /Delaunay Triangulation/delaunay.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Stanford notebook 3 | ----------------------------------------------------- 4 | Delaunay Algorithm Does not handle degenerate cases 5 | Running time: O(n^4) 6 | INPUT: x[] = x-coordinates 7 | y[] = y-coordinates 8 | OUTPUT: triples = a vector containing m triples 9 | (indices corresponding to triangle vertices) 10 | ----------------------------------------------------- 11 | */ 12 | 13 | typedef double T; 14 | 15 | struct triple { 16 | int i, j, k; 17 | triple() {} 18 | triple(int i, int j, int k) : i(i), j(j), k(k) {} 19 | }; 20 | 21 | vector delaunayTriangulation(vector& x, vector& y) 22 | { 23 | int n = x.size(); 24 | vector z(n); 25 | vector ret; 26 | 27 | for (int i = 0; i < n; i++) 28 | z[i] = x[i] * x[i] + y[i] * y[i]; 29 | for (int i = 0; i < n-2; i++) 30 | { 31 | for (int j = i+1; j < n; j++) 32 | { 33 | for (int k = i+1; k < n; k++) 34 | { 35 | if (j == k) continue; 36 | double xn = (y[j]-y[i])*(z[k]-z[i]) - (y[k]-y[i])*(z[j]-z[i]); 37 | double yn = (x[k]-x[i])*(z[j]-z[i]) - (x[j]-x[i])*(z[k]-z[i]); 38 | double zn = (x[j]-x[i])*(y[k]-y[i]) - (x[k]-x[i])*(y[j]-y[i]); 39 | bool flag = zn < 0; 40 | for (int m = 0; flag && m < n; m++) 41 | flag = flag && ((x[m]-x[i])*xn + (y[m]-y[i])*yn + (z[m]-z[i])*zn <= 0); 42 | if (flag) ret.push_back(triple(i, j, k)); 43 | } 44 | } 45 | } 46 | return ret; 47 | } 48 | 49 | int main() { 50 | T xs[]={0, 0, 1, 0.9}; 51 | T ys[]={0, 1, 0, 0.9}; 52 | vector x(&xs[0], &xs[4]), y(&ys[0], &ys[4]); 53 | vector tri = delaunayTriangulation(x, y); 54 | //expected: 0 1 3 55 | // 0 3 2 56 | int i; 57 | for(i = 0; i < tri.size(); i++) 58 | printf("%d %d %d\n", tri[i].i, tri[i].j, tri[i].k); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /Disjoint Set Union (DSU)/dsu.cpp: -------------------------------------------------------------------------------- 1 | class UF { 2 | int *id, cnt, *sz; 3 | public: 4 | // Create an empty union find data structure with N isolated sets. 5 | UF(int N) { 6 | cnt = N; 7 | id = new int[N]; 8 | sz = new int[N]; 9 | for(int i=0; i 2 | #define MAXN 1000005 3 | using namespace std; 4 | 5 | long long etf[MAXN]; 6 | 7 | void cal_etf() 8 | { 9 | for(int i = 1 ;i <= MAXN ; i++ ) 10 | etf[i]=i; 11 | for(int i=2 ; i<= MAXN ; i++ ) 12 | if ( etf[i] == i) 13 | for(int j = 2*i ; j <= MAXN ; j += i) 14 | etf[j] -= etf[j]/ i ; 15 | 16 | etf[1]=1; 17 | for(int i=2 ; i<= MAXN ; i++) { 18 | if ( etf[i]==i) //if that number is prime 19 | etf[i] = i-1; 20 | } 21 | } 22 | 23 | int main() 24 | { 25 | cal_etf(); 26 | for(int i=1;i<=10;i++) cout< 4 | using namespace std; 5 | #define ll long long 6 | #define ld double 7 | #define vi vector 8 | #define vll vector 9 | #define print(s) cout<<#s<<" : ";for(auto i:(s))cout< & a, bool invert) { 44 | int n = (int) a.size(); 45 | 46 | for (int i=1, j=0; i> 1; 48 | for (; j>=bit; bit>>=1) 49 | j -= bit; 50 | j += bit; 51 | if (i < j) 52 | swap (a[i], a[j]); 53 | } 54 | for (int len=2; len<=n; len<<=1) { 55 | for (int i=0; i P(n), Q(n); 75 | int SQRTMOD = (int)sqrt(mod) + 10; 76 | for(int i = 0;i < n1;i++) P[i] = base(a[i] % SQRTMOD, a[i] / SQRTMOD); 77 | for(int i = 0;i < n2;i++) Q[i] = base(b[i] % SQRTMOD, b[i] / SQRTMOD); 78 | fft(P, 0); 79 | fft(Q, 0); 80 | base A1, A2, B1, B2, X, Y; 81 | for(int i = 0; i < n; i++){ 82 | X = P[i]; 83 | Y = P[(n - i) % n].conj(); 84 | A1 = (X + Y) * base(0.5, 0); 85 | A2 = (X - Y) * base(0, -0.5); 86 | X = Q[i]; 87 | Y = Q[(n - i) % n].conj(); 88 | B1 = (X + Y) * base(0.5, 0); 89 | B2 = (X - Y) * base(0, -0.5); 90 | P1[i] = A1 * B1 + A2 * B2 * base(0, 1); 91 | Q1[i] = A1 * B2 + A2 * B1; 92 | } 93 | for(int i = 0; i < n; i++) P[i] = P1[i], Q[i] = Q1[i]; 94 | fft(P, 1); 95 | fft(Q, 1); 96 | a.resize(final_size); 97 | for(int i = 0; i < final_size; i++){ 98 | ll x = (ll)(P[i].real() + 0.5); 99 | ll y = (ll)(P[i].imag() + 0.5) % mod; 100 | ll z = (ll)(Q[i].real() + 0.5); 101 | a[i] = (x + ((y * SQRTMOD + z) % mod) * SQRTMOD) % mod; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /FFT/fft_float.cpp: -------------------------------------------------------------------------------- 1 | // Source: https://discuss.codechef.com/t/notd-editorial/104445 2 | #include 3 | #define ll long long int 4 | 5 | using namespace std; 6 | namespace FFT { 7 | using float_t = double; 8 | 9 | struct cd { 10 | float_t x, y; 11 | cd(float_t x = 0, float_t y = 0): x(x), y(y) {} 12 | friend ostream& operator<<(ostream& os, const cd& c) { 13 | return os << '(' << c.x << ", " << c.y << ')'; 14 | } 15 | 16 | float_t real() const { return x; } 17 | float_t imag() const { return y; } 18 | 19 | cd& operator+=(const cd& o) { x += o.x, y += o.y; return *this; } 20 | cd operator+(const cd& o) const { cd ret = *this; ret += o; return ret; } 21 | 22 | cd& operator-=(const cd& o) { x -= o.x, y -= o.y; return *this; } 23 | cd operator-(const cd& o) const { cd ret = *this; ret -= o; return ret; } 24 | 25 | cd& operator*=(const cd& o) { tie(x, y) = make_pair(x * o.x - y * o.y, x * o.y + y * o.x); return *this; } 26 | cd operator*(const cd& o) const { cd ret = *this; ret *= o; return ret; } 27 | 28 | cd& operator/=(const float_t& r) { x /= r, y /= r; return *this; } 29 | cd operator/(const float_t& r) const { cd ret = *this; ret /= r; return ret; } 30 | 31 | }; 32 | 33 | const float_t PI = acos(float_t(-1)); 34 | const int FFT_CUTOFF = 150; 35 | vector roots = {{0, 0}, {1, 0}}, inv_roots = {{0, 0}, {1, 0}}; 36 | vector bit_order; 37 | 38 | void prepare_roots(int n) { 39 | if(roots.size() >= n) return; 40 | int len = roots.size(); 41 | roots.resize(n); inv_roots.resize(n); 42 | while(n > len) { 43 | const cd w(cos(PI / len), sin(PI / len)), inv_w(w.real(), -w.imag()); 44 | for(int i = len >> 1; i < len; i++) { 45 | roots[i << 1] = roots[i]; 46 | roots[i << 1 | 1] = roots[i] * w; 47 | inv_roots[i << 1] = inv_roots[i]; 48 | inv_roots[i << 1 | 1] = inv_roots[i] * inv_w; 49 | } len <<= 1; 50 | } 51 | } 52 | 53 | void reorder_bits(int n, vector& a) { 54 | if(bit_order.size() != n) { 55 | bit_order.assign(n, 0); 56 | int len = __builtin_ctz(n); 57 | for(int i = 0; i < n; i++) 58 | bit_order[i] = (bit_order[i >> 1] >> 1) + ((i & 1) << len-1); 59 | } 60 | for(int i = 0; i < n; i++) 61 | if(i > bit_order[i]) swap(a[i], a[bit_order[i]]); 62 | } 63 | 64 | void fft(int n, vector& a, bool invert = false) { 65 | prepare_roots(n); reorder_bits(n, a); 66 | const auto& ws = invert? inv_roots : roots; 67 | for(int len = 1; len < n; len <<= 1) 68 | for(int i = 0; i < n; i += len << 1) 69 | for(int j = 0; j < len; j++) { 70 | const cd& even = a[i + j]; 71 | cd odd = a[i + len + j] * ws[len + j]; 72 | a[i + len + j] = even - odd; a[i + j] = even + odd; 73 | } 74 | if(invert) 75 | for(auto& x: a) x /= n; 76 | } 77 | 78 | template 79 | vector multiply(const vector& a, const vector& b, bool trim = false) { 80 | int n = a.size(), m = b.size(); 81 | if(n == 0 or m == 0) 82 | return vector{0}; 83 | 84 | if(min(n, m) < FFT_CUTOFF) { 85 | vector res(n + m - 1); 86 | for(int i = 0; i < n; i++) 87 | for(int j = 0; j < m; j++) 88 | res[i + j] += a[i] * b[j]; 89 | 90 | if(trim) { 91 | while(!res.empty() && res.back() == 0) 92 | res.pop_back(); 93 | } 94 | 95 | return res; 96 | } 97 | 98 | int N = [](int x) { while(x & x-1) x = (x | x-1) + 1; return x; }(n + m - 1); 99 | vector fa(a.begin(), a.end()), fb(b.begin(), b.end()); 100 | fa.resize(N); fb.resize(N); 101 | 102 | bool equal = n == m and a == b; 103 | fft(N, fa); 104 | 105 | if(equal) fb = fa; 106 | else fft(N, fb); 107 | 108 | for(int i = 0; i < N; i++) 109 | fa[i] *= fb[i]; 110 | 111 | fft(N, fa, true); 112 | 113 | fa.resize(n + m - 1); 114 | vector res(n + m - 1); 115 | for(int i = 0; i < n + m - 1; i++) 116 | res[i] = is_integral::value? round(fa[i].real()) : fa[i].real(); 117 | 118 | if(trim) { 119 | while(!res.empty() && res.back() == 0) 120 | res.pop_back(); 121 | } 122 | 123 | return res; 124 | } 125 | 126 | template 127 | T expo(T A, int64_t B) { 128 | T res{1}; while(B) { 129 | if(B & 1) res = res * A; 130 | B >>= 1; A = A * A; 131 | } return res; 132 | } 133 | 134 | template 135 | vector expo(const vector& a, int e, bool trim = false) { 136 | int n = a.size(); 137 | int N = [](int x) { while(x & x-1) x = (x | x-1) + 1; return x; }((n-1) * e + 1); 138 | vector fa(a.begin(), a.end()); fa.resize(N); 139 | 140 | fft(N, fa); 141 | 142 | for(int i = 0; i < N; i++) 143 | fa[i] = expo(fa[i], e); 144 | 145 | fft(N, fa, true); 146 | 147 | fa.resize((n-1) * e + 1); 148 | vector res((n-1) * e + 1); 149 | for(int i = 0; i < res.size(); i++) 150 | res[i] = is_integral::value? round(fa[i].real()) : fa[i].real(); 151 | 152 | if(trim) { 153 | while(!res.empty() && res.back() == 0) 154 | res.pop_back(); 155 | } 156 | 157 | return res; 158 | } 159 | 160 | } // namespace FFT 161 | -------------------------------------------------------------------------------- /Fast Sieve/fast_sieve.cpp: -------------------------------------------------------------------------------- 1 | // compute prime numbers to N really fast (Sieve) 2 | #define N 10000100 3 | vector primes; 4 | char p[N/8]; 5 | 6 | void GeneratePrimes() 7 | { 8 | primes.push_back(2); 9 | int i,j; 10 | for(i=1;((i*i)<<1)+(i<<1)>3]&(1<<(i&7)))==0) 13 | { 14 | primes.push_back((i<<1)+1); 15 | for(j=((i*i)<<1)+(i<<1),k=(i<<1)+1;(j<<1)+1>3] |=(1<<(j&7)); 18 | } 19 | } 20 | } 21 | 22 | for(;(i<<1)+1>3]&(1<<(i&7)))==0) 25 | { 26 | primes.push_back((i<<1)+1); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Fibonacci/fast_doubling.cpp: -------------------------------------------------------------------------------- 1 | /* Fast Doubling Method - Fibonacci */ 2 | #include 3 | #define REP(i,n) for (int i = 1; i <= n; i++) 4 | using namespace std; 5 | 6 | typedef long long ll; 7 | 8 | map F; 9 | 10 | ll m=1000000007; 11 | 12 | long long f(long long n) { 13 | if (F.count(n)) 14 | return F[n]; 15 | long long k = n / 2; 16 | if (n % 2 == 0) { // n=2*k 17 | return F[n] = (f(k) * f(k) + f(k - 1) * f(k - 1)) % m; 18 | } else { // n=2*k+1 19 | return F[n] = (f(k) * f(k + 1) + f(k - 1) * f(k)) % m; 20 | } 21 | } 22 | 23 | int main() 24 | { 25 | F[0] = F[1] = 1; 26 | ll n;cin >> n; // This answers the term n 27 | cout << f(n-1); 28 | } 29 | -------------------------------------------------------------------------------- /Heavy Light Decomposition/HLD.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define pb push_back 5 | #define sz size 6 | #define all(X) (X).begin(), (X).end () 7 | #define for_each(it, X) for (__typeof((X).begin()) it = (X).begin(); it != (X).end(); it++) 8 | 9 | 10 | typedef long long int lld; 11 | typedef pair < int, int > pii; 12 | 13 | const int MaxN = 1 << 20; 14 | 15 | int N, M, Level[MaxN], Parent[MaxN], Size[MaxN], Chain[MaxN]; 16 | vector < int > E[MaxN]; 17 | void DFS ( int Curr, int Prev ) 18 | { 19 | Parent[Curr] = Prev; 20 | Size[Curr] = 1; 21 | 22 | for_each ( it, E[Curr] ) 23 | if ( * it != Prev ) 24 | Level[* it] = Level[Curr] + 1, DFS ( * it, Curr ), Size[Curr] += Size[* it]; 25 | /* So basically for each of the element in their we need to have 26 | level which tells your dist from root 27 | size which is the number of your children 28 | parent which is the index of your dad which is unique obviously 29 | */ 30 | } 31 | /*The Hld function is initialized from the root and for every node connected to it 32 | their onwards we need to check that we don't make hld from where we came 33 | so basically i have a few children one of which is my special children i keep recursively 34 | looking for my special children and color them with my own color but what about 35 | my other children i give them another children and tell them to start a new family themselves 36 | this is all that i do only after i take care of all my special children*/ 37 | void HLD ( int Curr, int Prev, int Color ) 38 | { 39 | Chain[Curr] = Color; 40 | 41 | int idx = -1; 42 | for_each ( it, E[Curr] ) 43 | if ( * it != Prev && ( idx == -1 || Size[* it] > Size[idx] ) ) 44 | idx = * it; 45 | 46 | 47 | if ( idx != -1 ) HLD ( idx, Curr, Color ); 48 | for_each ( it, E[Curr] ) if ( * it != Prev && * it != idx ) HLD ( * it, Curr, * it ); 49 | } 50 | /* 51 | This is a simple function to find lca it works in O(n) and its not really cool 52 | but its their, however their is an improvised version of this thing called 53 | Logarithmic LCA which can be learnt later 54 | */ 55 | inline int LCA ( int idx, int idy ) 56 | { 57 | while ( Chain[idx] != Chain[idy] ) 58 | if ( Level[Chain[idx]] < Level[Chain[idy]] ) idy = Parent[Chain[idy]]; 59 | else idx = Parent[Chain[idx]]; 60 | 61 | return Level[idx] < Level[idy] ? idx : idy; 62 | } 63 | 64 | int main ( void ) 65 | { 66 | 67 | 68 | cin >> N >> M; /*Scan the vertices and queries for the tree */ 69 | for ( int i = 0; i < N - 1; i++ ) 70 | { 71 | int idx, idy; 72 | cin >> idx >> idy; 73 | idx--; 74 | idy--; 75 | 76 | E[idx].pb ( idy ); 77 | E[idy].pb ( idx ); /*connect the edges*/ 78 | } 79 | 80 | DFS ( 0, -1 ); 81 | HLD ( 0, -1, 0 ); 82 | 83 | for ( int i = 0; i < M; i++ ) 84 | { 85 | int idx, idy; 86 | cin >> idx >> idy; 87 | idx--; 88 | idy--; 89 | 90 | cout << LCA ( idx, idy ) + 1 << endl; 91 | } 92 | 93 | return 0; 94 | } -------------------------------------------------------------------------------- /Implicit Segment Tree/implicit_segment_tree.cpp: -------------------------------------------------------------------------------- 1 | // Implicit segment tree , support range update [L-R] and point query. 2 | 3 | // Also handle queries when intitially array is emmpty , and 1 <= L , R <= 1e9 4 | 5 | #include 6 | #define ll long long 7 | 8 | using namespace std; 9 | 10 | struct Implicit_segment_tree { 11 | ll Sum; 12 | Implicit_segment_tree *left , *right; 13 | Implicit_segment_tree(ll _Sum , Implicit_segment_tree *_left , Implicit_segment_tree *_right ){ 14 | Sum = _Sum; 15 | left = _left; 16 | right = _right; 17 | } 18 | }; 19 | 20 | void update(Implicit_segment_tree *root , int l , int r , int s , int e , ll value ){ 21 | if(s > r || l > e ) 22 | return; 23 | if(l >= s && r <= e ){ 24 | root->Sum += value; 25 | return; 26 | } 27 | if(root->left == NULL) 28 | root->left = new Implicit_segment_tree(0 , NULL , NULL); 29 | if(root->right == NULL) 30 | root->right = new Implicit_segment_tree(0 , NULL , NULL); 31 | update(root->left , l , (l + r)/2 , s , e , value ); 32 | update(root->right , (l + r)/2 + 1 , r , s, e , value); 33 | } 34 | 35 | ll query(Implicit_segment_tree *root , int l , int r, int idx) { 36 | if( root == NULL || idx > r || l > idx ) 37 | return 0; 38 | if( l == r ) 39 | return root->Sum; 40 | return root->Sum + query(root->left , l , ( l + r)/2 , idx) + query( root->right , (l + r)/2 + 1 , r, idx); 41 | } 42 | 43 | 44 | int main() { 45 | int N , Q; 46 | scanf("%d%d",&N,&Q); 47 | Implicit_segment_tree *root = new Implicit_segment_tree(0 , NULL, NULL); 48 | for(int i = 1 ; i <= N ; ++i ){ 49 | int x; 50 | scanf("%d",&x); 51 | update(root , 1 , N , i , i , x ); 52 | } 53 | while(Q--){ 54 | int choice; 55 | scanf("%d",&choice); // choice 1 for update , 2 for query at index x 56 | if(choice == 1){ 57 | int L , R , value; 58 | scanf("%d%d%d",&L,&R,&value); 59 | update(root, 1 , N , L , R , value ); 60 | } else { 61 | int idx; 62 | scanf("%d",&idx); 63 | printf("%lld\n",query(root, 1 , N , idx)); 64 | } 65 | } 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /Li Chao Tree/li_chao_tree.py: -------------------------------------------------------------------------------- 1 | # Problem: https://atcoder.jp/contests/abc244/tasks/abc244_h 2 | # AC Submission from Editorial: https://atcoder.jp/contests/abc244/submissions/30307939 3 | 4 | class LiChaoTree: 5 | # Min Query 6 | def __init__(self, X): # X: 調べる可能性のある x 座標のリスト 7 | X = sorted(list(set(X))) 8 | self.inf = 10 ** 50 9 | self.n = 1 << (len(X) - 1).bit_length() 10 | self.X = X + [self.inf] * (self.n - len(X)) 11 | self.D = {a: i for i, a in enumerate(X)} 12 | self.lmr = [(0, 0, 0)] * self.n + [(x, x, x) for x in self.X] 13 | for i in range(1, self.n)[::-1]: 14 | self.lmr[i] = (self.lmr[i*2][0], self.lmr[i*2][2], self.lmr[i*2^1][2]) 15 | self.F = [None] * (self.n * 2) 16 | 17 | def calc(self, f, x): 18 | return f[0] * x + f[1] 19 | 20 | def update(self, i, f): 21 | while 1: 22 | l, m, r = self.lmr[i] 23 | fi = self.F[i] 24 | if fi is None: 25 | self.F[i] = f 26 | return 27 | cl = (fi[0] - f[0]) * l + fi[1] - f[1] > 0 28 | cr = (fi[0] - f[0]) * r + fi[1] - f[1] > 0 29 | 30 | if cl and cr: 31 | self.F[i] = f 32 | return 33 | if not cl and not cr: 34 | return 35 | if (fi[0] - f[0]) * m + fi[1] - f[1] > 0: 36 | self.F[i], f = f, fi 37 | cl = not cl 38 | if cl: 39 | i *= 2 40 | else: 41 | i = i * 2 + 1 42 | 43 | def query(self, x): 44 | i = self.D[x] + self.n 45 | mi = self.inf 46 | while i > 0: 47 | if self.F[i]: 48 | mi = min(mi, self.calc(self.F[i], x)) 49 | i >>= 1 50 | return mi 51 | 52 | def add_line(self, a, b): # y = ax + b 53 | f = (a, b) 54 | self.update(1, f) 55 | 56 | def debug(self): 57 | print("F =", self.F) 58 | print("X =", self.X) 59 | print("D =", self.D) 60 | print("lmr =", self.lmr) 61 | -------------------------------------------------------------------------------- /Longest Increasing Subsequence/LIS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int LIS() 7 | { 8 | int n; 9 | cin>>n; // Number of elements 10 | vector d; // A possible solution that is one of the Longest Increasing Subsequences 11 | int elem; 12 | for(int i=0;i>elem; 15 | //vector::iterator it = upper_bound(d.begin(),d.end(),elem); // non-decreasing 16 | vector::iterator it = lower_bound(d.begin(),d.end(),elem); // strictly increasing 17 | if(it == d.end()) d.push_back(elem); 18 | else *it=elem; 19 | } 20 | cout< 2 | using namespace std; 3 | //reference http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html 4 | //a sample problem which needs this algorithm - http://www.spoj.com/problems/MSUBSTR/ 5 | int manacher_algorithm(string x) 6 | { 7 | string y="#"; 8 | int l=x.length(); 9 | int i=0; 10 | int len=0; 11 | int p[10001]={0}; //array for preprocessing 12 | int c=0,r=0,i_mirror=0; 13 | for(i=0;ii)?min(r-i,p[i_mirror]):0; 24 | while(i-p[i]-1>=0 && p[i]+i-1r) //reassgining center of palindrome at p[i] 29 | { 30 | r=p[i]+i; 31 | c=i; 32 | } 33 | } 34 | int max_val=INT_MIN; 35 | for(i=0;imax_val) 38 | max_val=p[i]; 39 | } 40 | int counter=0; 41 | for(i=0;i>t; 52 | while(t--) 53 | { 54 | cin>>x; 55 | manacher_algorithm(x); 56 | } 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Matrix/matrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | //#pragma GCC optimize("Ofast") 4 | //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") 5 | 6 | #define ms(s, n) memset(s, n, sizeof(s)) 7 | #define FOR(i, a, b) for (int i = (a); i < (b); ++i) 8 | #define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i) 9 | #define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++) 10 | #define sz(a) int((a).size()) 11 | #define pconent(t, x) (t.find(x) != t.end()) 12 | #define all(a) (a).begin(), (a).end() 13 | #define uni(a) (a).erase(unique(all(a)), (a).end()) 14 | #define pb push_back 15 | #define pf push_front 16 | #define mp make_pair 17 | #define fi first 18 | #define se second 19 | #define prec(n) fixed<> (i)) & 1) 21 | #define bitcount(n) __builtin_popcountll(n) 22 | typedef long long ll; 23 | typedef unsigned long long ull; 24 | typedef long double ld; 25 | typedef pair pi; 26 | typedef vector vi; 27 | typedef vector vii; 28 | const int MOD = (int) 1e9 + 7; 29 | const int FFTMOD = 1007681537; 30 | const int INF = (int) 1e9; 31 | const ll LINF = (ll) 1e18; 32 | const ld PI = acos((ld) -1); 33 | const ld EPS = 1e-9; 34 | inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;} 35 | inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;} 36 | inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;} 37 | template inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;} 38 | template inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;} 39 | inline ll isqrt(ll k) {ll r = sqrt(k) + 1; while (r * r > k) r--; return r;} 40 | inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;} 41 | inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;} 42 | inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;} 43 | inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;} 44 | inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);} 45 | inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;} 46 | inline int sign(ld x, ld y) {return sign(x - y);} 47 | #define db(x) cerr << #x << " = " << (x) << " "; 48 | #define endln cerr << "\n"; 49 | 50 | struct Matrix { 51 | static const int MAXN = 55; 52 | int x[MAXN][MAXN]; 53 | 54 | Matrix() { 55 | memset(x, 0, sizeof(x)); 56 | } 57 | int* operator [] (int r) { 58 | return x[r]; 59 | } 60 | static Matrix unit() { 61 | Matrix res; 62 | for (int i = 0; i < MAXN; i++) res[i][i] = 1; 63 | return res; 64 | } 65 | friend Matrix operator + (Matrix A, Matrix B) { 66 | Matrix res; 67 | for (int i = 0; i < MAXN; i++) for (int j = 0; j < MAXN; j++) { 68 | res[i][j] = A[i][j] + B[i][j]; 69 | if (res[i][j] >= MOD) res[i][j] -= MOD; 70 | } 71 | return res; 72 | } 73 | friend Matrix operator * (Matrix A, Matrix B) { 74 | Matrix res; 75 | for (int i = 0; i < MAXN; i++) for (int j = 0; j < MAXN; j++) { 76 | long long SQMOD = (long long) MOD * MOD; 77 | long long sum = 0; 78 | for (int k = 0; k < MAXN; k++) { 79 | sum += (long long) A[i][k] * B[k][j]; 80 | if (sum >= SQMOD) sum -= SQMOD; 81 | } 82 | res[i][j] = sum % MOD; 83 | } 84 | return res; 85 | } 86 | friend Matrix operator ^ (Matrix A, long long k) { 87 | if (k == 0) return unit(); 88 | Matrix res, tmp; 89 | for (int i = 0; i < MAXN; i++) for (int j = 0; j < MAXN; j++) { 90 | res[i][j] = tmp[i][j] = A[i][j]; 91 | } 92 | k--; 93 | while (k) { 94 | if (k & 1) res = res * tmp; 95 | tmp = tmp * tmp; 96 | k >>= 1; 97 | } 98 | return res; 99 | } 100 | }; 101 | -------------------------------------------------------------------------------- /Max Flow/dinic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct flow_graph{ 8 | int MAX_V,E,s,t,head,tail; 9 | int *cap,*to,*next,*last,*dist,*q,*now; 10 | 11 | flow_graph(){} 12 | 13 | flow_graph(int V, int MAX_E){ 14 | MAX_V = V; E = 0; 15 | cap = new int[2*MAX_E], to = new int[2*MAX_E], next = new int[2*MAX_E]; 16 | last = new int[MAX_V], q = new int[MAX_V], dist = new int[MAX_V], now = new int[MAX_V]; 17 | fill(last,last+MAX_V,-1); 18 | } 19 | 20 | void clear(){ 21 | fill(last,last+MAX_V,-1); 22 | E = 0; 23 | } 24 | 25 | void add_edge(int u, int v, int uv, int vu = 0){ 26 | to[E] = v, cap[E] = uv, next[E] = last[u]; last[u] = E++; 27 | to[E] = u, cap[E] = vu, next[E] = last[v]; last[v] = E++; 28 | } 29 | 30 | bool bfs(){ 31 | fill(dist,dist+MAX_V,-1); 32 | head = tail = 0; 33 | 34 | q[tail] = t; ++tail; 35 | dist[t] = 0; 36 | 37 | while(head0 && dist[to[e]]==-1){ 42 | q[tail] = to[e]; ++tail; 43 | dist[to[e]] = dist[v]+1; 44 | } 45 | } 46 | } 47 | 48 | return dist[s]!=-1; 49 | } 50 | 51 | int dfs(int v, int f){ 52 | if(v==t) return f; 53 | 54 | for(int &e = now[v];e!=-1;e = next[e]){ 55 | if(cap[e]>0 && dist[to[e]]==dist[v]-1){ 56 | int ret = dfs(to[e],min(f,cap[e])); 57 | 58 | if(ret>0){ 59 | cap[e] -= ret; 60 | cap[e^1] += ret; 61 | return ret; 62 | } 63 | } 64 | } 65 | 66 | return 0; 67 | } 68 | 69 | long long max_flow(int source, int sink){ 70 | s = source; t = sink; 71 | long long f = 0; 72 | int x; 73 | 74 | while(bfs()){ 75 | for(int i = 0;i if level.(w) < 0 && c.(i) > 0 then ( 34 | level.(w) <- level.(v) + 1; 35 | push w 36 | ) 37 | ) adj.(v); 38 | loop () 39 | ) 40 | in 41 | level.(s) <- 0; 42 | back := 0; front := 0; 43 | push s; 44 | loop (); 45 | in 46 | 47 | let rec dfs v cap = 48 | (* Does a DFS from v looking for a path to t. It tries to push cap units 49 | of flow to t. It returns the amount of flow actually pushed *) 50 | if v=t then cap else 51 | let rec loop total remaining li = 52 | match li with 53 | | [] -> 54 | alive.(v) <- []; 55 | total 56 | | (w,i)::tail -> 57 | if level.(w) = level.(v)+1 && c.(i) > 0 then ( 58 | let p = dfs w (min c.(i) remaining) in 59 | c.(i) <- c.(i) - p; 60 | c.(i lxor 1) <- c.(i lxor 1) + p; 61 | if remaining-p = 0 then ( 62 | alive.(v) <- li; 63 | total+p 64 | ) else loop (total+p) (remaining-p) tail 65 | ) else loop total remaining tail 66 | in loop 0 cap alive.(v) 67 | in 68 | 69 | let rec main_loop flow_so_far = 70 | Array.fill level 0 n (-1); 71 | Array.blit adj 0 alive 0 n; 72 | if bfs () then main_loop (flow_so_far + (dfs s infinite_c)) else (flow_so_far, c) 73 | in 74 | main_loop 0 75 | 76 | (* end flow *) 77 | 78 | let rec fold i j f init = if i>j then init else fold (i+1) j f (f i init) 79 | let sum i j f = fold i j (fun i a -> (f i) + a) 0 80 | 81 | open Printf 82 | open Scanf 83 | 84 | let read_int _ = bscanf Scanning.stdib " %d " (fun x -> x) 85 | let read_pair _ = bscanf Scanning.stdin " %d %d " (fun x y -> (x,y)) 86 | 87 | let () = 88 | let cases = read_int() in 89 | for case = 1 to cases do 90 | 91 | let (n,m) = read_pair () in 92 | 93 | let nn = n + m + 2 in 94 | 95 | let graph = Array.make nn [] in 96 | 97 | let index = ref 0 in 98 | let add_edge u v = 99 | let i = !index in 100 | graph.(u) <- (v,i)::graph.(u); 101 | graph.(v) <- (u,i+1)::graph.(v); 102 | index := i+2 103 | in 104 | 105 | let (s,t) = (nn-2, nn-1) in 106 | 107 | for day=0 to m-1 do 108 | let k = read_int() in 109 | for j = 0 to k-1 do 110 | let f = -1 + read_int() in 111 | add_edge day (m+f) 112 | done; 113 | done; 114 | 115 | for day=0 to m-1 do 116 | add_edge s day; 117 | done; 118 | 119 | for friend=m to n+m-1 do 120 | add_edge friend t; 121 | done; 122 | 123 | let mm = !index in 124 | 125 | let cap = Array.init mm (fun i -> (i+1) land 1) in 126 | 127 | for friend = m to n+m-1 do 128 | List.iter (fun (v,i) -> if v = t then cap.(i) <- (m+1)/2) graph.(friend) 129 | done; 130 | let (f,final_cap) = maxflow s t graph cap in 131 | if f < m then printf "NO\n" else ( 132 | printf "YES\n"; 133 | for day = 0 to m-1 do 134 | List.iter (fun (v,j) -> 135 | if v <> s && final_cap.(j) = 0 then 136 | printf "%d " (v-m+1)) graph.(day) 137 | done; 138 | print_newline() 139 | ) 140 | done 141 | -------------------------------------------------------------------------------- /Max Flow/maxflow_topcoder.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define pb push_back 3 | #define mp make_pair 4 | #define INF 0x3f3f3f3f 5 | #define MAXN 310 6 | using namespace std; 7 | 8 | class MaxFlow { 9 | public: 10 | vector > initial_g, g; // initial_g: stores initial capacities which should not be changed. 11 | vector vis, from; 12 | int n, s, t; // no. of vertices, src, dst 13 | MaxFlow(int vertices) { 14 | n = vertices+1; // 0&1 based graphs both handled 15 | initial_g = vector >(n, vector(n,0)); 16 | g = vector >(n, vector(n,0)); 17 | } 18 | void add_edge(int u, int v, int w) { 19 | initial_g[u][v] = w; 20 | g[u][v] = w; 21 | } 22 | 23 | int bfs_augment() { 24 | vis = vector(n,0); 25 | from = vector(n,-1); 26 | 27 | queue q; 28 | q.push(s); 29 | vis[s] = true; 30 | 31 | int where; 32 | bool reached; 33 | reached = false; 34 | 35 | // find augmenting path 36 | while(!q.empty()) { 37 | where = q.front(); 38 | q.pop(); 39 | for(int i=0;i 0) { 42 | q.push(next); 43 | vis[next] = true; 44 | from[next] = where; 45 | if(next == t) { // if sink reached, augmenting path is found. 46 | reached = true; 47 | break; 48 | } 49 | } 50 | } 51 | if(reached) break; 52 | } 53 | 54 | int prev; 55 | int path_capacity = INF; 56 | where = t; 57 | while(from[where] > -1) { // path capacity = minimum edge in path 58 | prev = from[where]; 59 | path_capacity = min(path_capacity, g[prev][where]); 60 | where = prev; 61 | } 62 | 63 | where = t; 64 | while(from[where] > -1) { // augment flow in graph by path capacity. 65 | prev = from[where]; 66 | g[prev][where] -= path_capacity; 67 | g[where][prev] += path_capacity; 68 | where = prev; 69 | } 70 | if(path_capacity == INF) return 0; 71 | else return path_capacity; 72 | } 73 | 74 | int pfs_augment() { 75 | vis = vector(n,0); 76 | from = vector(n,-1); 77 | 78 | struct node { 79 | int vertex, priority, from; 80 | node(int v,p,f) { 81 | vertex = v, priority = p, from = f; 82 | } 83 | } 84 | priority_queue pq; 85 | pq.push(node(s,INF,-1)); 86 | int path_capacity = 0; 87 | while(!pq.empty()) { 88 | node aux = pq.top(); 89 | pq.pop(); 90 | 91 | int where = aux.vertex, cost = aux.priority; 92 | if(vis[where]) continue; 93 | from[where] = aux.from; 94 | 95 | if(where == sink) { 96 | path_capacity = cost; 97 | break; 98 | } 99 | 100 | vis[where] = true; 101 | for(int next=0;next 0) { 103 | int new_cost = min(cost, g[where][next]); 104 | pq.push(node(next,new_cost,where)); 105 | } 106 | } 107 | } 108 | 109 | int where = sink; 110 | while(from[where] > -1) { 111 | int prev = from[where]; 112 | g[prev][where] -= path_capacity; 113 | g[where][prev] += path_capacity; 114 | where = prev; 115 | } 116 | 117 | return path_capacity; 118 | } 119 | 120 | int get_max_flow(int _s, int _t) { 121 | s = _s, t = _t; 122 | int flow = 0; 123 | while(int increment = bfs_augment()) { 124 | flow += increment; 125 | } 126 | return flow; 127 | } 128 | 129 | void disp() { 130 | cerr << endl; 131 | cerr << "Flow from " << s << " to " << t << endl; 132 | for(int i = 0; i < n; ++i) for(int j = 0; j < n; ++j) if(initial_g[i][j] > 0) { 133 | cerr << i << " " << j << " " << g[i][j] << "/" << initial_g[i][j] << endl; 134 | } 135 | cerr << endl; 136 | } 137 | }; 138 | 139 | int main() { 140 | int n,m; 141 | cin>>n>>m; 142 | MaxFlow f(n); 143 | int u,v,w; 144 | for(int i=0;i>u>>v>>w; 146 | f.add_edge(u,v,w); 147 | } 148 | cout< 7 | #include 8 | 9 | struct rep { 10 | struct iter { 11 | int i; 12 | constexpr void operator++() { ++i; } 13 | constexpr int operator*() const { return i; } 14 | friend constexpr bool operator!=(iter a, iter b) { return *a != *b; } 15 | }; 16 | const int l, r; 17 | constexpr rep(int _l, int _r) : l(std::min(_l, _r)), r(_r) {} 18 | constexpr rep(int n) : rep(0, n) {} 19 | constexpr iter begin() const { return {l}; } 20 | constexpr iter end() const { return {r}; } 21 | }; 22 | struct per { 23 | struct iter { 24 | int i; 25 | constexpr void operator++() { --i; } 26 | constexpr int operator*() const { return i; } 27 | friend constexpr bool operator!=(iter a, iter b) { return *a != *b; } 28 | }; 29 | const int l, r; 30 | constexpr per(int _l, int _r) : l(std::min(_l, _r)), r(_r) {} 31 | constexpr per(int n) : per(0, n) {} 32 | constexpr iter begin() const { return {r - 1}; } 33 | constexpr iter end() const { return {l - 1}; } 34 | }; 35 | template 36 | constexpr bool chmin(T& a, U&& b) { 37 | return b < a ? a = std::forward(b), true : false; 38 | } 39 | template 40 | constexpr bool chmax(T& a, U&& b) { 41 | return a < b ? a = std::forward(b), true : false; 42 | } 43 | 44 | namespace atcoder { 45 | 46 | template 47 | struct mcf_graph { 48 | public: 49 | mcf_graph() {} 50 | mcf_graph(int n) : _n(n), g(n) {} 51 | 52 | int add_edge(int from, int to, Cap cap, Cost cost) { 53 | assert(0 <= from && from < _n); 54 | assert(0 <= to && to < _n); 55 | int m = int(pos.size()); 56 | pos.push_back({from, int(g[from].size())}); 57 | int from_id = int(g[from].size()); 58 | int to_id = int(g[to].size()); 59 | if (from == to) to_id++; 60 | g[from].push_back(_edge{to, to_id, cap, cost}); 61 | g[to].push_back(_edge{from, from_id, 0, -cost}); 62 | return m; 63 | } 64 | 65 | struct edge { 66 | int from, to; 67 | Cap cap, flow; 68 | Cost cost; 69 | }; 70 | 71 | edge get_edge(int i) { 72 | int m = int(pos.size()); 73 | assert(0 <= i && i < m); 74 | auto _e = g[pos[i].first][pos[i].second]; 75 | auto _re = g[_e.to][_e.rev]; 76 | return edge{ 77 | pos[i].first, _e.to, _e.cap + _re.cap, _re.cap, _e.cost, 78 | }; 79 | } 80 | std::vector edges() { 81 | int m = int(pos.size()); 82 | std::vector result(m); 83 | for (int i = 0; i < m; i++) { 84 | result[i] = get_edge(i); 85 | } 86 | return result; 87 | } 88 | 89 | std::pair flow(int s, int t) { 90 | return flow(s, t, std::numeric_limits::max()); 91 | } 92 | std::pair flow(int s, int t, Cap flow_limit) { 93 | return slope(s, t, flow_limit).back(); 94 | } 95 | std::vector> slope(int s, int t) { 96 | return slope(s, t, std::numeric_limits::max()); 97 | } 98 | std::vector> slope(int s, int t, Cap flow_limit) { 99 | assert(0 <= s && s < _n); 100 | assert(0 <= t && t < _n); 101 | assert(s != t); 102 | // variants (C = maxcost): 103 | // -(n-1)C <= dual[s] <= dual[i] <= dual[t] = 0 104 | // reduced cost (= e.cost + dual[e.from] - dual[e.to]) >= 0 for all edge 105 | std::vector dual(_n, 0), dist(_n); 106 | std::vector pv(_n), pe(_n); 107 | std::vector vis(_n); 108 | auto dual_ref = [&]() { 109 | std::fill(dist.begin(), dist.end(), std::numeric_limits::max()); 110 | std::fill(pv.begin(), pv.end(), -1); 111 | std::fill(pe.begin(), pe.end(), -1); 112 | std::fill(vis.begin(), vis.end(), false); 113 | struct Q { 114 | Cost key; 115 | int to; 116 | bool operator<(Q r) const { return key > r.key; } 117 | }; 118 | std::priority_queue que; 119 | dist[s] = 0; 120 | que.push(Q{0, s}); 121 | while (!que.empty()) { 122 | int v = que.top().to; 123 | que.pop(); 124 | if (vis[v]) continue; 125 | vis[v] = true; 126 | if (v == t) break; 127 | // dist[v] = shortest(s, v) + dual[s] - dual[v] 128 | // dist[v] >= 0 (all reduced cost are positive) 129 | // dist[v] <= (n-1)C 130 | for (int i = 0; i < int(g[v].size()); i++) { 131 | auto e = g[v][i]; 132 | if (vis[e.to] || !e.cap) continue; 133 | // |-dual[e.to] + dual[v]| <= (n-1)C 134 | // cost <= C - -(n-1)C + 0 = nC 135 | Cost cost = e.cost - dual[e.to] + dual[v]; 136 | if (dist[e.to] - dist[v] > cost) { 137 | dist[e.to] = dist[v] + cost; 138 | pv[e.to] = v; 139 | pe[e.to] = i; 140 | que.push(Q{dist[e.to], e.to}); 141 | } 142 | } 143 | } 144 | if (!vis[t]) { 145 | return false; 146 | } 147 | 148 | for (int v = 0; v < _n; v++) { 149 | if (!vis[v]) continue; 150 | // dual[v] = dual[v] - dist[t] + dist[v] 151 | // = dual[v] - (shortest(s, t) + dual[s] - dual[t]) + 152 | // (shortest(s, v) + dual[s] - dual[v]) = - shortest(s, t) + 153 | // dual[t] + shortest(s, v) = shortest(s, v) - shortest(s, t) >= 154 | // 0 - (n-1)C 155 | dual[v] -= dist[t] - dist[v]; 156 | } 157 | return true; 158 | }; 159 | Cap flow = 0; 160 | Cost cost = 0, prev_cost_per_flow = -1; 161 | std::vector> result; 162 | result.push_back({flow, cost}); 163 | while (flow < flow_limit) { 164 | if (!dual_ref()) break; 165 | Cap c = flow_limit - flow; 166 | for (int v = t; v != s; v = pv[v]) { 167 | c = std::min(c, g[pv[v]][pe[v]].cap); 168 | } 169 | for (int v = t; v != s; v = pv[v]) { 170 | auto& e = g[pv[v]][pe[v]]; 171 | e.cap -= c; 172 | g[v][e.rev].cap += c; 173 | } 174 | Cost d = -dual[s]; 175 | flow += c; 176 | cost += c * d; 177 | if (prev_cost_per_flow == d) { 178 | result.pop_back(); 179 | } 180 | result.push_back({flow, cost}); 181 | prev_cost_per_flow = d; 182 | } 183 | return result; 184 | } 185 | 186 | private: 187 | int _n; 188 | 189 | struct _edge { 190 | int to, rev; 191 | Cap cap; 192 | Cost cost; 193 | }; 194 | 195 | std::vector> pos; 196 | std::vector> g; 197 | }; 198 | 199 | } // namespace atcoder 200 | 201 | template 202 | struct min_cost_b_flow { 203 | struct result { 204 | bool feasible; 205 | Cost cost; 206 | std::vector flow; 207 | std::vector dual; 208 | }; 209 | 210 | min_cost_b_flow() {} 211 | explicit min_cost_b_flow(int n) : g(n + 2), b(n) {} 212 | 213 | int size() const { return std::size(b); } 214 | int add_edge(int src, int dst, Cap lower, Cap upper, Cost cost) { 215 | assert(0 <= src), assert(src < size()); 216 | assert(0 <= dst), assert(dst < size()); 217 | assert(lower <= upper); 218 | if (rev.push_back(cost < 0), rev.back()) { 219 | std::swap(src, dst); 220 | std::tie(lower, upper) = std::pair{-upper, -lower}; 221 | cost = -cost; 222 | } 223 | b[src] -= lower; 224 | b[dst] += lower; 225 | res.cost += lower * cost; 226 | res.flow.push_back(lower); 227 | return g.add_edge(src, dst, upper - lower, cost); 228 | } 229 | void add_supply(int v, Cap x) { 230 | assert(0 <= v), assert(v < size()); 231 | b[v] += x; 232 | } 233 | void add_demand(int v, Cap x) { 234 | assert(0 <= v), assert(v < size()); 235 | b[v] -= x; 236 | } 237 | 238 | result flow() { 239 | int source = size(), sink = source + 1; 240 | Cap positive{}, negative{}; 241 | for (int v = 0; v < size(); ++v) 242 | if (b[v] > 0) { 243 | g.add_edge(source, v, b[v], 0); 244 | positive += b[v]; 245 | } else if (b[v] < 0) { 246 | g.add_edge(v, sink, -b[v], 0); 247 | negative += -b[v]; 248 | } 249 | if (positive != negative) return {}; 250 | auto [flow, cost] = g.flow(source, sink); 251 | if (flow < positive) return {}; 252 | res.feasible = true; 253 | res.cost += cost; 254 | std::vector>> h(size()); 255 | for (int i = 0; i < int(std::size(res.flow)); ++i) { 256 | auto e = g.get_edge(i); 257 | if (e.flow < e.cap) h[e.from].emplace_back(e.to, e.cost); 258 | if (e.flow > 0) h[e.to].emplace_back(e.from, -e.cost); 259 | res.flow[i] += e.flow; 260 | if (rev[i]) res.flow[i] = -res.flow[i]; 261 | } 262 | res.dual.resize(size()); 263 | std::vector que(size()); 264 | std::iota(begin(que), end(que), 0); 265 | std::vector in_que(size(), true); 266 | for (int bg = 0; bg < int(std::size(que));) { 267 | int v = que[bg++]; 268 | in_que[v] = false; 269 | for (auto [u, c] : h[v]) { 270 | if (res.dual[v] + c < res.dual[u]) { 271 | res.dual[u] = res.dual[v] + c; 272 | if (not in_que[u]) in_que[u] = true, que.push_back(u); 273 | } 274 | } 275 | } 276 | return res; 277 | } 278 | 279 | private: 280 | atcoder::mcf_graph g; 281 | std::vector b; 282 | std::vector rev; 283 | result res{}; 284 | }; 285 | 286 | int main() { 287 | using namespace std; 288 | cin.tie(nullptr)->sync_with_stdio(false); 289 | int n, m; 290 | cin >> n >> m; 291 | min_cost_b_flow g(n); 292 | while (m--) { 293 | int x, y, w; 294 | cin >> x >> y >> w; 295 | --x, --y; 296 | g.add_edge(x, y, -1e7, w, 1); 297 | } 298 | auto ans = g.flow().dual; 299 | auto mx = *max_element(begin(ans), end(ans)); 300 | for (auto&& e : ans) e = mx - e; 301 | for (int i : rep(n)) cout << ans[i] << " \n"[i == n - 1]; 302 | } 303 | -------------------------------------------------------------------------------- /Misc/order_of_prime_in_factorial.py: -------------------------------------------------------------------------------- 1 | # https://www.hackerrank.com/contests/infinitum-jul14/challenges/order-of-prime-in-factorial/problem 2 | 3 | def S(p,n): 4 | return 0 if n == 0 else (n%p) + S(p,n/p) 5 | 6 | def G(p,L): 7 | Q,R = divmod(L,p) 8 | return Q + ((-S(p,Q)) % p < R) 9 | 10 | def F_(p,L): 11 | Q,R = divmod(L,p) 12 | return p*G(p,Q) + R*(S(p,Q) % p == 0) 13 | 14 | def F(p,L): 15 | return F_(p,L+1) - 1 16 | 17 | for cas in xrange(input()): 18 | p,L = map(int, raw_input().strip().split()) 19 | print F(p,L) 20 | -------------------------------------------------------------------------------- /Mo/even_odd_mo.cpp: -------------------------------------------------------------------------------- 1 | // Credits: Aeren 2 | // https://codeforces.com/contest/1511/submission/112913505 3 | 4 | #include 5 | using namespace std; 6 | 7 | // Reorder N 2D points with max_x - min_x <= X, max_y - min_y <= Y 8 | // so that sum(abs(xi - x(i+1)) + abs(yi - y(i+1)) is small 9 | // and process queries on the new order. 10 | // N BX inc_x and dec_x calls, X Y / BX inc_y and dec_y calls at max 11 | // set BX = sqrt(X Y / N) to achieve sqrt(X Y N) calls at max 12 | template 13 | struct mo_2d{ 14 | vector> points; // x, y, ind 15 | void insert(int x, int y, int id){ 16 | points.push_back({x, y, id}); 17 | } 18 | // starting from (0, 0), access each points and execute queries 19 | void solve(auto inc_x, auto dec_x, auto inc_y, auto dec_y, auto process){ 20 | auto cmp = [&](const auto &p, const auto &q)->bool{ 21 | return p[0] / BX != q[0] / BX ? p < q : p[0] / BX & 1 ? p[1] < q[1] : p[1] > q[1]; 22 | }; 23 | sort(points.begin(), points.end(), cmp); 24 | int x = 0, y = 0; 25 | for(auto &[qx, qy, id]: points){ 26 | while(qx < x) dec_x(), -- x; 27 | while(y < qy) inc_y(), ++ y; 28 | while(x < qx) inc_x(), ++ x; 29 | while(qy < y) dec_y(), -- y; 30 | process(id); 31 | } 32 | } 33 | }; 34 | 35 | int main(){ 36 | cin.tie(0)->sync_with_stdio(0); 37 | cin.exceptions(ios::badbit | ios::failbit); 38 | int n, m; 39 | cin >> n >> m; 40 | vector flag(m); 41 | for(auto i = 0; i < n; ++ i){ 42 | int x; 43 | cin >> x, -- x; 44 | flag[x] ^= 1; 45 | } 46 | int qn; 47 | cin >> qn; 48 | mo_2d mo; 49 | for(auto qi = 0; qi < qn; ++ qi){ 50 | int l, r; 51 | cin >> l >> r, -- l; 52 | mo.insert(l, r, qi); 53 | } 54 | int l = 0, r = 0, xor_sum = 0; 55 | const int mx = __lg(m) + 1; 56 | vector> cnt(mx); 57 | for(auto bit = 0; bit < mx; ++ bit){ 58 | cnt[bit].assign(1 << bit, 0); 59 | } 60 | auto inc_x = [&](){ 61 | if(flag[l]){ 62 | for(auto bit = 0; bit < mx; ++ bit){ 63 | cnt[bit].front() ^= true; 64 | } 65 | } 66 | for(auto bit = 0; bit < mx; ++ bit){ 67 | xor_sum ^= cnt[bit].front() << bit; 68 | cnt[bit].push_back(cnt[bit].front()); 69 | cnt[bit].pop_front(); 70 | } 71 | ++ l; 72 | }; 73 | auto dec_x = [&](){ 74 | -- l; 75 | for(auto bit = 0; bit < mx; ++ bit){ 76 | xor_sum ^= cnt[bit].back() << bit; 77 | cnt[bit].push_front(cnt[bit].back()); 78 | cnt[bit].pop_back(); 79 | } 80 | if(flag[l]){ 81 | for(auto bit = 0; bit < mx; ++ bit){ 82 | cnt[bit][0] ^= true; 83 | } 84 | } 85 | }; 86 | auto inc_y = [&](){ 87 | if(flag[r]){ 88 | int x = r - l; 89 | xor_sum ^= x; 90 | for(auto bit = 0; bit < mx; ++ bit){ 91 | cnt[bit][x & (1 << bit) - 1] ^= true; 92 | } 93 | } 94 | ++ r; 95 | }; 96 | auto dec_y = [&](){ 97 | -- r; 98 | if(flag[r]){ 99 | int x = r - l; 100 | xor_sum ^= x; 101 | for(auto bit = 0; bit < mx; ++ bit){ 102 | cnt[bit][x & (1 << bit) - 1] ^= true; 103 | } 104 | } 105 | }; 106 | string res(qn, '?'); 107 | auto process = [&](int qi){ 108 | res[qi] = 'A' + !xor_sum; 109 | }; 110 | mo.solve(inc_x, dec_x, inc_y, dec_y, process); 111 | cout << res << "\n"; 112 | return 0; 113 | } 114 | 115 | /* 116 | 117 | */ 118 | 119 | //////////////////////////////////////////////////////////////////////////////////////// 120 | // // 121 | // Coded by Aeren // 122 | // // 123 | //////////////////////////////////////////////////////////////////////////////////////// 124 | -------------------------------------------------------------------------------- /Order Statistic Tree/ost.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace __gnu_pbds; 5 | using namespace std; 6 | template 7 | using ordered_set = tree, rb_tree_tag, tree_order_statistics_node_update>; 8 | 9 | int main(){ 10 | ordered_set s; 11 | s.insert(1); 12 | s.insert(3); 13 | cout << s.order_of_key(2) << endl; // the number of elements in the s less than 2 14 | cout << *s.find_by_order(0) << endl; // print the 0-th smallest number in s(0-based) 15 | } 16 | -------------------------------------------------------------------------------- /Palindromic Tree/pal_tree_template.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long int 5 | #define LD long double 6 | 7 | const int N = 100010; 8 | 9 | int inf = 1e9; 10 | int mod = 1e9 + 7; 11 | 12 | 13 | struct PalindromicTree { 14 | 15 | struct node { 16 | int next[26], suffixlink, len; 17 | int cnt, num; 18 | node(int l = 0) : suffixlink(0), len(l), cnt(0), num(0) { 19 | for(int i = 0; i < 26; i++) 20 | next[i] = 0; 21 | } 22 | }; 23 | 24 | vector state; 25 | vector s; 26 | int last, n; 27 | 28 | PalindromicTree() { 29 | last = 1; 30 | n = 0; 31 | state.push_back(0); 32 | state.push_back(-1); 33 | state[0].suffixlink = 1; 34 | s.push_back(-1); //Breaking character 35 | } 36 | 37 | void reset() { 38 | state.clear(); 39 | s.clear(); 40 | last = 1; 41 | n = 0; 42 | state.push_back(0); 43 | state.push_back(-1); 44 | state[0].suffixlink = 1; 45 | s.push_back(-1); //Breaking character 46 | } 47 | 48 | int get_link(int x) { 49 | while(s[n - state[x].len - 1] != s[n]) { 50 | x = state[x].suffixlink; 51 | } 52 | return x; 53 | } 54 | 55 | void add(char nxt) { 56 | int c = nxt - 'a'; 57 | s.push_back(c); 58 | n++; 59 | int cur = get_link(last); 60 | 61 | if(!state[cur].next[c]) { 62 | int now = state.size(); 63 | state.push_back(state[cur].len + 2); 64 | state[now].suffixlink = state[get_link(state[cur].suffixlink)].next[c]; 65 | state[cur].next[c] = now; 66 | state[now].num = state[state[now].suffixlink].num + 1; 67 | } 68 | 69 | last = state[cur].next[c]; 70 | state[last].cnt++; 71 | } 72 | 73 | int size() { 74 | return state.size() - 2; 75 | } 76 | }; 77 | -------------------------------------------------------------------------------- /Palindromic Tree/palindromic_tree.cpp: -------------------------------------------------------------------------------- 1 | const int maxn = 1e5, k = 26; 2 | 3 | int s[maxn], len[maxn], link[maxn], to[maxn][k]; 4 | 5 | int n, last, sz; 6 | 7 | void init () { 8 | s[n++] = -1; 9 | link[0] = 1; 10 | len[1] = -1; 11 | sz = 2; 12 | } 13 | 14 | int get_link (int v) { 15 | while (s[n-len[v]-2] != s[n-1]) v = link[v]; 16 | return v; 17 | } 18 | 19 | void add_letter (int c) { 20 | s[n++] = c; 21 | last = get_link(last); 22 | if (!to[last][c]) { 23 | len[sz] = len[last] + 2; 24 | link[sz] = to[get_link(link[last])][c]; 25 | to[last][c] = sz++; 26 | } 27 | last = to[last][c]; 28 | } 29 | -------------------------------------------------------------------------------- /Persistent Segment Tree/chemthan_pst.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | /* 5 | * Complexity: O(logN) 6 | */ 7 | const int MAXN = 3e6 + 5; 8 | int ptr; 9 | struct Node { 10 | Node *l, *r; 11 | int L, R, cnt; 12 | Node(); 13 | } mem[MAXN], *nil = mem + MAXN - 1; 14 | Node::Node() { 15 | l = r = nil; 16 | L = R = -1; 17 | cnt = 0; 18 | } 19 | Node* newNode() { 20 | return mem + (ptr++); 21 | } 22 | Node* build(int L, int R) { 23 | Node* node = newNode(); 24 | node->L = L; node->R = R; 25 | if (L == R) return node; 26 | node->l = build(L, (L + R) >> 1); 27 | node->r = build(((L + R) >> 1) + 1, R); 28 | return node; 29 | } 30 | Node* update(Node* node, int i, int val) { 31 | if (node->L > i || node->R < i) return node; 32 | Node* x = newNode(); 33 | x->L = node->L; x->R = node->R; 34 | x->l = node->l; x->r = node->r; 35 | if (node->L == node->R) { 36 | x->cnt = node->cnt + val; 37 | return x; 38 | } 39 | x->l = update(x->l, i, val); 40 | x->r = update(x->r, i, val); 41 | x->cnt = x->l->cnt + x->r->cnt; 42 | return x; 43 | } 44 | int query(Node* node, int L, int R) { 45 | if (node->L > R || node->R < L) return 0; 46 | if (node->L >= L && node->R <= R) return node->cnt; 47 | return query(node->l, L, R) + query(node->r, L, R); 48 | } 49 | 50 | Node* root[MAXN]; 51 | 52 | int main() { 53 | int n = 10; 54 | root[0] = build(0, n - 1); 55 | root[1] = update(root[0], 2, 4); 56 | root[2] = update(root[1], 3, 1); 57 | cout << query(root[2], 0, 3) << "\n"; //Expected 5 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Persistent Segment Tree/persistent_segtree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define INF (int)1e9 5 | #define forall(i,a,b) for(int i=a;i (b) ? (a) : (b)) 21 | #define abs(a) ( (a) > (0) ? (a) : (-a)) 22 | #define miN(a,b) ( (a) < (b) ? (a) : (b)) 23 | #define checkbit(n,b) ( (n >> b) & 1) 24 | #define DREP(a) sort(all(a)); a.erase(unique(all(a)),a.end()) //deletes repeat 25 | 26 | // The bit standard guys 27 | #define bit(x,i) (x&(1< vi; 34 | typedef vector vvi; 35 | typedef pair ii; 36 | #define ft first 37 | #define sd second 38 | 39 | // the data types 40 | #define ll long long 41 | #define st string 42 | 43 | int a[10000],s[10000],n,NEXT_FREE_INDEX = 1,root[10000],L[10000],R[10000],ir; 44 | 45 | /* 46 | Here is how the persistent segtree worksWe have an array a1,a2,...,an and at first q update queries 47 | and then u ask queries which you have to answer online. 48 | 49 | Each update query gives you numbers p and v and asks you to increase ap by v . 50 | 51 | Each ask query, gives you three numbers i and x and y and asks you to print the value of ax1+ax2+...+ay after 52 | performing ith query.Each update query, changes the value of O(log(n)) nodes in the segment tree, 53 | so you should keep rest of nodes (not containing p) and create log(n) new nodes. Totally, you need 54 | to have q.log(n) nodes. So, you can not use normal segment's indexing, you should keep the index of 55 | children in the arrays L and R. 56 | If you update a node, you should assign a new index to its interval (for i-th query). 57 | 58 | You should keep an array root[q] which gives you the index of the interval of the root ( [0,n) ) 59 | after performing each query and a number ir=0 which is its index in the initial 60 | segment tree (ans of course, an array s[MAXNODES] which is the sum of elements in that node). 61 | Also you should have a NEXT_FREE_INDEX = 1 which is always the next free index for a node. 62 | 63 | First of all, you need to build the initial segment tree : 64 | 65 | (In these codes, all arrays and queries are 0-based) 66 | 67 | 68 | */ 69 | 70 | void build(int id = ir,int l = 0,int r = n){ 71 | if(r - l < 2){ 72 | s[id] = a[l]; 73 | return ; 74 | } 75 | int mid = (l+r)/2; 76 | L[id] = NEXT_FREE_INDEX ++; 77 | R[id] = NEXT_FREE_INDEX ++; 78 | build(L[id], l, mid); 79 | build(R[id], mid, r); 80 | s[id] = s[L[id]] + s[R[id]]; 81 | 82 | } 83 | 84 | int upd(int p, int v,int id,int l = 0,int r = n){ 85 | int ID = NEXT_FREE_INDEX ++; // index of the node in new version of segment tree 86 | if(r - l < 2){ 87 | s[ID] = (a[p] += v); 88 | return ID; 89 | } 90 | int mid = (l+r)/2; 91 | L[ID] = L[id], R[ID] = R[id]; // in case of not updating the interval of left child or right child 92 | if(p < mid) 93 | L[ID] = upd(p, v, L[ID], l, mid); 94 | else 95 | R[ID] = upd(p, v, R[ID], mid, r); 96 | s[ID]=s[L[ID]]+s[R[ID]]; 97 | 98 | return ID; 99 | 100 | } 101 | 102 | int sum(int x,int y,int id,int l = 0,int r = n){ 103 | if(x >= r or l >= y) return 0; 104 | if(x <= l && r <= y) return s[id]; 105 | int mid = (l+r)/2; 106 | return sum(x, y, L[id], l, mid) + 107 | sum(x, y, R[id], mid, r); 108 | } 109 | 110 | int main() 111 | { 112 | cout << " the orignal segtre \n"; 113 | a[0]=4;a[1]=7;a[2]=2;a[3]=3;a[4]=5;a[5]=9; 114 | // Query type 1,0,number of elements 115 | build(0,0,6); 116 | 117 | /*Word of CAUTION (For the first query (with index 0) we should run root[0]=upd(p, v, ir) and 118 | for the rest of them,for j-th query se should run root[j]=upd(p, v,root[j-1]) )*/ 119 | cout << "The origninal thing is \n"; 120 | forall(i,0,25)cout << s[i] <<" ";cout << "\n"; 121 | root[0]=upd(0,2,0,0,6); 122 | root[1]=upd(2,1,root[0],0,6); 123 | root[2]=upd(1,4,root[1],0,6); 124 | cout << "the changed thing is \n"; 125 | forall(i,0,25)cout << s[i] <<" ";cout << "\n"; 126 | int k=sum(0,3,0,0,6);cout << k <<"\n"; 127 | k=sum(0,3,root[0],0,6);cout << k <<"\n"; 128 | k=sum(0,3,root[1],0,6);cout << k <<"\n"; 129 | k=sum(0,3,root[2],0,6);cout << k <<"\n"; 130 | } -------------------------------------------------------------------------------- /Polynomial/Polynomial.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int fpow(int n, int k, int p) { 5 | int r = 1; 6 | for (; k; k >>= 1) { 7 | if (k & 1) r = (long long) r * n % p; 8 | n = (long long) n * n % p; 9 | } 10 | return r; 11 | } 12 | 13 | struct Polynomial { 14 | //nirjhor's code 15 | static const int maxn = 1e3 + 5; 16 | static const int limit = 1e3; 17 | static const int mod = (int) 1e9 + 7; 18 | int deg; 19 | vector cof; 20 | Polynomial(int deg = 0) : deg(deg){ 21 | cof.resize(deg + 1, 0); 22 | } 23 | void init(int deg) { 24 | this->deg = deg; 25 | cof.resize(deg + 1, 0); 26 | for (int i = 0; i <= deg; i++) { 27 | cof[i] = 0; 28 | } 29 | } 30 | void shrink() { 31 | cof.resize(deg + 1); 32 | } 33 | friend Polynomial product(Polynomial f, Polynomial g) { 34 | Polynomial h(f.deg + g.deg); 35 | for (int i = 0; i <= f.deg; i++) { 36 | for (int j = 0; j <= g.deg; j++) { 37 | h.cof[i + j] = (h.cof[i + j] + (long long) f.cof[i] * g.cof[j]) % mod; 38 | } 39 | } 40 | return h; 41 | } 42 | //Assuming deg f >= deg g 43 | friend Polynomial quotient(Polynomial f, Polynomial g) { 44 | Polynomial q(f.deg - g.deg); 45 | for (int i = q.deg; i >= 0; i--) { 46 | q.cof[i] = (long long) f.cof[g.deg + i] * fpow(g.cof[g.deg], mod - 2, mod) % mod; 47 | for (int j = g.deg; j >= 0; j--) { 48 | f.cof[i + j] = (f.cof[i + j] - (long long) q.cof[i] * g.cof[j] % mod + mod) % mod; 49 | } 50 | } 51 | return q; 52 | } 53 | friend Polynomial remainder(Polynomial f, Polynomial g) { 54 | if (f.deg < g.deg) return f; 55 | for (int i = f.deg - g.deg; i >= 0; i--) { 56 | int c = (long long) f.cof[g.deg + i] * fpow(g.cof[g.deg], mod - 2, mod) % mod; 57 | for (int j = g.deg; j >= 0; j--) { 58 | f.cof[i + j] = (f.cof[i + j] - (long long) c * g.cof[j] % mod + mod) % mod; 59 | } 60 | } 61 | f.deg = g.deg - 1; 62 | while (!f.cof[f.deg]) f.deg--; 63 | f.deg = max(f.deg, 0); 64 | f.shrink(); 65 | return f; 66 | } 67 | //Assuming deg f >= deg g 68 | friend Polynomial gcd(Polynomial f, Polynomial g) { 69 | if (!g.deg && !g.cof[0]) return f; 70 | return gcd(g, remainder(f, g)); 71 | } 72 | //Cantor-Zassenhaus Algorithm 73 | friend vector findroots(Polynomial f) { 74 | srand(time(NULL)); 75 | vector res; 76 | if (f.deg == 1) { 77 | int root = (mod - (long long) f.cof[0] * fpow(f.cof[1], mod - 2, mod) % mod) % mod; 78 | res.push_back(root); 79 | return res; 80 | } 81 | int it = 0; 82 | while (it++ < limit) { 83 | int d = rand() % mod; 84 | Polynomial a(1), r(0); 85 | a.cof[1] = 1, a.cof[0] = d; 86 | r.cof[0] = 1; 87 | int k = (mod - 1) >> 1; 88 | while (k) { 89 | if (k & 1) r = remainder(product(r, a), f); 90 | a = remainder(product(a, a), f); 91 | k >>= 1; 92 | } 93 | r.cof[0]--; 94 | a = gcd(f, r); 95 | if (a.deg > 0 && a.deg < f.deg) { 96 | r = quotient(f, a); 97 | res = findroots(a); 98 | vector res2 = findroots(r); 99 | res.insert(res.end(), res2.begin(), res2.end()); 100 | it = 0; 101 | return res; 102 | } 103 | } 104 | return res; 105 | } 106 | } poly; 107 | 108 | const int mod = (int) 1e9 + 7; 109 | 110 | int main() { 111 | poly.init(3); 112 | poly.cof[0] = 1; 113 | poly.cof[1] = mod - 3; 114 | poly.cof[2] = 3; 115 | poly.cof[3] = mod - 1; 116 | vector root = findroots(poly); 117 | for (int i = 0; i < (int) root.size(); i++) { 118 | cout << root[i] << " \n"[i == (int) root.size() - 1]; //Expected: 1 1 1 119 | } 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /Polynomial/adamant_poly.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CP_ALGO_ALGEBRA_POLY_HPP 2 | #define CP_ALGO_ALGEBRA_POLY_HPP 3 | #include "poly/impl/euclid.hpp" 4 | #include "poly/impl/base.hpp" 5 | #include "poly/impl/div.hpp" 6 | #include "number_theory.hpp" 7 | #include "fft.hpp" 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | namespace cp_algo::algebra { 16 | template 17 | struct poly_t { 18 | using base = T; 19 | std::vector a; 20 | 21 | void normalize() {poly::impl::normalize(*this);} 22 | 23 | poly_t(){} 24 | poly_t(T a0): a{a0} {normalize();} 25 | poly_t(std::vector const& t): a(t) {normalize();} 26 | 27 | poly_t operator -() const {return poly::impl::neg(*this);} 28 | poly_t& operator += (poly_t const& t) {return poly::impl::add(*this, t);} 29 | poly_t& operator -= (poly_t const& t) {return poly::impl::sub(*this, t);} 30 | poly_t operator + (poly_t const& t) const {return poly_t(*this) += t;} 31 | poly_t operator - (poly_t const& t) const {return poly_t(*this) -= t;} 32 | 33 | poly_t mod_xk(size_t k) const {return poly::impl::mod_xk(*this, k);} // %= x^k 34 | poly_t mul_xk(size_t k) const {return poly::impl::mul_xk(*this, k);} // *= x^k 35 | poly_t div_xk(size_t k) const {return poly::impl::div_xk(*this, k);} // /= x^k 36 | poly_t substr(size_t l, size_t k) const {return poly::impl::substr(*this, l, k);} 37 | 38 | poly_t operator *= (const poly_t &t) {fft::mul(a, t.a); normalize(); return *this;} 39 | poly_t operator * (const poly_t &t) const {return poly_t(*this) *= t;} 40 | 41 | poly_t& operator /= (const poly_t &t) {return *this = divmod(t)[0];} 42 | poly_t& operator %= (const poly_t &t) {return *this = divmod(t)[1];} 43 | poly_t operator / (poly_t const& t) const {return poly_t(*this) /= t;} 44 | poly_t operator % (poly_t const& t) const {return poly_t(*this) %= t;} 45 | 46 | poly_t& operator *= (T const& x) {return *this = poly::impl::scale(*this, x);} 47 | poly_t& operator /= (T const& x) {return *this *= x.inv();} 48 | poly_t operator * (T const& x) const {return poly_t(*this) *= x;} 49 | poly_t operator / (T const& x) const {return poly_t(*this) /= x;} 50 | 51 | poly_t reverse(size_t n) const {return poly::impl::reverse(*this, n);} 52 | poly_t reverse() const {return reverse(size(a));} 53 | 54 | std::array divmod(poly_t const& b) const { 55 | return poly::impl::divmod(*this, b); 56 | } 57 | 58 | // reduces A/B to A'/B' such that 59 | // deg B' < deg A / 2 60 | static std::pair, linfrac> half_gcd(auto &&A, auto &&B) { 61 | return poly::impl::half_gcd(A, B); 62 | } 63 | // reduces A / B to gcd(A, B) / 0 64 | static std::pair, linfrac> full_gcd(auto &&A, auto &&B) { 65 | return poly::impl::full_gcd(A, B); 66 | } 67 | static poly_t gcd(poly_t &&A, poly_t &&B) { 68 | full_gcd(A, B); 69 | return A; 70 | } 71 | 72 | // Returns a (non-monic) characteristic polynomial 73 | // of the minimum linear recurrence for the sequence 74 | poly_t min_rec(size_t d) const { 75 | return poly::impl::min_rec(*this, d); 76 | } 77 | 78 | // calculate inv to *this modulo t 79 | std::optional inv_mod(poly_t const& t) const { 80 | return poly::impl::inv_mod(*this, t); 81 | }; 82 | 83 | poly_t negx() const { // A(x) -> A(-x) 84 | auto res = *this; 85 | for(int i = 1; i <= deg(); i += 2) { 86 | res.a[i] = -res[i]; 87 | } 88 | return res; 89 | } 90 | 91 | void print(int n) const { 92 | for(int i = 0; i < n; i++) { 93 | std::cout << (*this)[i] << ' '; 94 | } 95 | std::cout << "\n"; 96 | } 97 | 98 | void print() const { 99 | print(deg() + 1); 100 | } 101 | 102 | T eval(T x) const { // evaluates in single point x 103 | T res(0); 104 | for(int i = deg(); i >= 0; i--) { 105 | res *= x; 106 | res += a[i]; 107 | } 108 | return res; 109 | } 110 | 111 | T lead() const { // leading coefficient 112 | assert(!is_zero()); 113 | return a.back(); 114 | } 115 | 116 | int deg() const { // degree, -1 for P(x) = 0 117 | return (int)a.size() - 1; 118 | } 119 | 120 | bool is_zero() const { 121 | return a.empty(); 122 | } 123 | 124 | T operator [](int idx) const { 125 | return idx < 0 || idx > deg() ? T(0) : a[idx]; 126 | } 127 | 128 | T& coef(size_t idx) { // mutable reference at coefficient 129 | return a[idx]; 130 | } 131 | 132 | bool operator == (const poly_t &t) const {return a == t.a;} 133 | bool operator != (const poly_t &t) const {return a != t.a;} 134 | 135 | poly_t deriv(int k = 1) const { // calculate derivative 136 | if(deg() + 1 < k) { 137 | return poly_t(T(0)); 138 | } 139 | std::vector res(deg() + 1 - k); 140 | for(int i = k; i <= deg(); i++) { 141 | res[i - k] = fact(i) * rfact(i - k) * a[i]; 142 | } 143 | return res; 144 | } 145 | 146 | poly_t integr() const { // calculate integral with C = 0 147 | std::vector res(deg() + 2); 148 | for(int i = 0; i <= deg(); i++) { 149 | res[i + 1] = a[i] * small_inv(i + 1); 150 | } 151 | return res; 152 | } 153 | 154 | size_t trailing_xk() const { // Let p(x) = x^k * t(x), return k 155 | if(is_zero()) { 156 | return -1; 157 | } 158 | int res = 0; 159 | while(a[res] == T(0)) { 160 | res++; 161 | } 162 | return res; 163 | } 164 | 165 | poly_t log(size_t n) const { // calculate log p(x) mod x^n 166 | assert(a[0] == T(1)); 167 | return (deriv().mod_xk(n) * inv(n)).integr().mod_xk(n); 168 | } 169 | 170 | poly_t exp(size_t n) const { // calculate exp p(x) mod x^n 171 | if(is_zero()) { 172 | return T(1); 173 | } 174 | assert(a[0] == T(0)); 175 | poly_t ans = T(1); 176 | size_t a = 1; 177 | while(a < n) { 178 | poly_t C = ans.log(2 * a).div_xk(a) - substr(a, 2 * a); 179 | ans -= (ans * C).mod_xk(a).mul_xk(a); 180 | a *= 2; 181 | } 182 | return ans.mod_xk(n); 183 | } 184 | 185 | poly_t pow_bin(int64_t k, size_t n) const { // O(n log n log k) 186 | if(k == 0) { 187 | return poly_t(1).mod_xk(n); 188 | } else { 189 | auto t = pow(k / 2, n); 190 | t = (t * t).mod_xk(n); 191 | return (k % 2 ? *this * t : t).mod_xk(n); 192 | } 193 | } 194 | 195 | poly_t circular_closure(size_t m) const { 196 | if(deg() == -1) { 197 | return *this; 198 | } 199 | auto t = *this; 200 | for(size_t i = t.deg(); i >= m; i--) { 201 | t.a[i - m] += t.a[i]; 202 | } 203 | t.a.resize(std::min(t.a.size(), m)); 204 | return t; 205 | } 206 | 207 | static poly_t mul_circular(poly_t const& a, poly_t const& b, size_t m) { 208 | return (a.circular_closure(m) * b.circular_closure(m)).circular_closure(m); 209 | } 210 | 211 | poly_t powmod_circular(int64_t k, size_t m) const { 212 | if(k == 0) { 213 | return poly_t(1); 214 | } else { 215 | auto t = powmod_circular(k / 2, m); 216 | t = mul_circular(t, t, m); 217 | if(k % 2) { 218 | t = mul_circular(t, *this, m); 219 | } 220 | return t; 221 | } 222 | } 223 | 224 | poly_t powmod(int64_t k, poly_t const& md) const { 225 | return poly::impl::powmod(*this, k, md); 226 | } 227 | 228 | // O(d * n) with the derivative trick from 229 | // https://codeforces.com/blog/entry/73947?#comment-581173 230 | poly_t pow_dn(int64_t k, size_t n) const { 231 | if(n == 0) { 232 | return poly_t(T(0)); 233 | } 234 | assert((*this)[0] != T(0)); 235 | std::vector Q(n); 236 | Q[0] = bpow(a[0], k); 237 | auto a0inv = a[0].inv(); 238 | for(int i = 1; i < (int)n; i++) { 239 | for(int j = 1; j <= std::min(deg(), i); j++) { 240 | Q[i] += a[j] * Q[i - j] * (T(k) * T(j) - T(i - j)); 241 | } 242 | Q[i] *= small_inv(i) * a0inv; 243 | } 244 | return Q; 245 | } 246 | 247 | // calculate p^k(n) mod x^n in O(n log n) 248 | // might be quite slow due to high constant 249 | poly_t pow(int64_t k, size_t n) const { 250 | if(is_zero()) { 251 | return k ? *this : poly_t(1); 252 | } 253 | int i = trailing_xk(); 254 | if(i > 0) { 255 | return k >= int64_t(n + i - 1) / i ? poly_t(T(0)) : div_xk(i).pow(k, n - i * k).mul_xk(i * k); 256 | } 257 | if(std::min(deg(), (int)n) <= magic) { 258 | return pow_dn(k, n); 259 | } 260 | if(k <= magic) { 261 | return pow_bin(k, n); 262 | } 263 | T j = a[i]; 264 | poly_t t = *this / j; 265 | return bpow(j, k) * (t.log(n) * T(k)).exp(n).mod_xk(n); 266 | } 267 | 268 | // returns std::nullopt if undefined 269 | std::optional sqrt(size_t n) const { 270 | if(is_zero()) { 271 | return *this; 272 | } 273 | int i = trailing_xk(); 274 | if(i % 2) { 275 | return std::nullopt; 276 | } else if(i > 0) { 277 | auto ans = div_xk(i).sqrt(n - i / 2); 278 | return ans ? ans->mul_xk(i / 2) : ans; 279 | } 280 | auto st = algebra::sqrt((*this)[0]); 281 | if(st) { 282 | poly_t ans = *st; 283 | size_t a = 1; 284 | while(a < n) { 285 | a *= 2; 286 | ans -= (ans - mod_xk(a) * ans.inv(a)).mod_xk(a) / 2; 287 | } 288 | return ans.mod_xk(n); 289 | } 290 | return std::nullopt; 291 | } 292 | 293 | poly_t mulx(T a) const { // component-wise multiplication with a^k 294 | T cur = 1; 295 | poly_t res(*this); 296 | for(int i = 0; i <= deg(); i++) { 297 | res.coef(i) *= cur; 298 | cur *= a; 299 | } 300 | return res; 301 | } 302 | 303 | poly_t mulx_sq(T a) const { // component-wise multiplication with a^{k choose 2} 304 | T cur = 1, total = 1; 305 | poly_t res(*this); 306 | for(int i = 0; i <= deg(); i++) { 307 | res.coef(i) *= total; 308 | cur *= a; 309 | total *= cur; 310 | } 311 | return res; 312 | } 313 | 314 | // be mindful of maxn, as the function 315 | // requires multiplying polynomials of size deg() and n+deg()! 316 | poly_t chirpz(T z, int n) const { // P(1), P(z), P(z^2), ..., P(z^(n-1)) 317 | if(is_zero()) { 318 | return std::vector(n, 0); 319 | } 320 | if(z == T(0)) { 321 | std::vector ans(n, (*this)[0]); 322 | if(n > 0) { 323 | ans[0] = accumulate(begin(a), end(a), T(0)); 324 | } 325 | return ans; 326 | } 327 | auto A = mulx_sq(z.inv()); 328 | auto B = ones(n+deg()).mulx_sq(z); 329 | return semicorr(B, A).mod_xk(n).mulx_sq(z.inv()); 330 | } 331 | 332 | // res[i] = prod_{1 <= j <= i} 1/(1 - z^j) 333 | static auto _1mzk_prod_inv(T z, int n) { 334 | std::vector res(n, 1), zk(n); 335 | zk[0] = 1; 336 | for(int i = 1; i < n; i++) { 337 | zk[i] = zk[i - 1] * z; 338 | res[i] = res[i - 1] * (T(1) - zk[i]); 339 | } 340 | res.back() = res.back().inv(); 341 | for(int i = n - 2; i >= 0; i--) { 342 | res[i] = (T(1) - zk[i+1]) * res[i+1]; 343 | } 344 | return res; 345 | } 346 | 347 | // prod_{0 <= j < n} (1 - z^j x) 348 | static auto _1mzkx_prod(T z, int n) { 349 | if(n == 1) { 350 | return poly_t(std::vector{1, -1}); 351 | } else { 352 | auto t = _1mzkx_prod(z, n / 2); 353 | t *= t.mulx(bpow(z, n / 2)); 354 | if(n % 2) { 355 | t *= poly_t(std::vector{1, -bpow(z, n - 1)}); 356 | } 357 | return t; 358 | } 359 | } 360 | 361 | poly_t chirpz_inverse(T z, int n) const { // P(1), P(z), P(z^2), ..., P(z^(n-1)) 362 | if(is_zero()) { 363 | return {}; 364 | } 365 | if(z == T(0)) { 366 | if(n == 1) { 367 | return *this; 368 | } else { 369 | return std::vector{(*this)[1], (*this)[0] - (*this)[1]}; 370 | } 371 | } 372 | std::vector y(n); 373 | for(int i = 0; i < n; i++) { 374 | y[i] = (*this)[i]; 375 | } 376 | auto prods_pos = _1mzk_prod_inv(z, n); 377 | auto prods_neg = _1mzk_prod_inv(z.inv(), n); 378 | 379 | T zn = bpow(z, n-1).inv(); 380 | T znk = 1; 381 | for(int i = 0; i < n; i++) { 382 | y[i] *= znk * prods_neg[i] * prods_pos[(n - 1) - i]; 383 | znk *= zn; 384 | } 385 | 386 | poly_t p_over_q = poly_t(y).chirpz(z, n); 387 | poly_t q = _1mzkx_prod(z, n); 388 | 389 | return (p_over_q * q).mod_xk(n).reverse(n); 390 | } 391 | 392 | static poly_t build(std::vector &res, int v, auto L, auto R) { // builds evaluation tree for (x-a1)(x-a2)...(x-an) 393 | if(R - L == 1) { 394 | return res[v] = std::vector{-*L, 1}; 395 | } else { 396 | auto M = L + (R - L) / 2; 397 | return res[v] = build(res, 2 * v, L, M) * build(res, 2 * v + 1, M, R); 398 | } 399 | } 400 | 401 | poly_t to_newton(std::vector &tree, int v, auto l, auto r) { 402 | if(r - l == 1) { 403 | return *this; 404 | } else { 405 | auto m = l + (r - l) / 2; 406 | auto A = (*this % tree[2 * v]).to_newton(tree, 2 * v, l, m); 407 | auto B = (*this / tree[2 * v]).to_newton(tree, 2 * v + 1, m, r); 408 | return A + B.mul_xk(m - l); 409 | } 410 | } 411 | 412 | poly_t to_newton(std::vector p) { 413 | if(is_zero()) { 414 | return *this; 415 | } 416 | int n = p.size(); 417 | std::vector tree(4 * n); 418 | build(tree, 1, begin(p), end(p)); 419 | return to_newton(tree, 1, begin(p), end(p)); 420 | } 421 | 422 | std::vector eval(std::vector &tree, int v, auto l, auto r) { // auxiliary evaluation function 423 | if(r - l == 1) { 424 | return {eval(*l)}; 425 | } else { 426 | auto m = l + (r - l) / 2; 427 | auto A = (*this % tree[2 * v]).eval(tree, 2 * v, l, m); 428 | auto B = (*this % tree[2 * v + 1]).eval(tree, 2 * v + 1, m, r); 429 | A.insert(end(A), begin(B), end(B)); 430 | return A; 431 | } 432 | } 433 | 434 | std::vector eval(std::vector x) { // evaluate polynomial in (x1, ..., xn) 435 | int n = x.size(); 436 | if(is_zero()) { 437 | return std::vector(n, T(0)); 438 | } 439 | std::vector tree(4 * n); 440 | build(tree, 1, begin(x), end(x)); 441 | return eval(tree, 1, begin(x), end(x)); 442 | } 443 | 444 | poly_t inter(std::vector &tree, int v, auto ly, auto ry) { // auxiliary interpolation function 445 | if(ry - ly == 1) { 446 | return {*ly / a[0]}; 447 | } else { 448 | auto my = ly + (ry - ly) / 2; 449 | auto A = (*this % tree[2 * v]).inter(tree, 2 * v, ly, my); 450 | auto B = (*this % tree[2 * v + 1]).inter(tree, 2 * v + 1, my, ry); 451 | return A * tree[2 * v + 1] + B * tree[2 * v]; 452 | } 453 | } 454 | 455 | static auto inter(std::vector x, std::vector y) { // interpolates minimum polynomial from (xi, yi) pairs 456 | int n = x.size(); 457 | std::vector tree(4 * n); 458 | return build(tree, 1, begin(x), end(x)).deriv().inter(tree, 1, begin(y), end(y)); 459 | } 460 | 461 | static auto resultant(poly_t a, poly_t b) { // computes resultant of a and b 462 | if(b.is_zero()) { 463 | return 0; 464 | } else if(b.deg() == 0) { 465 | return bpow(b.lead(), a.deg()); 466 | } else { 467 | int pw = a.deg(); 468 | a %= b; 469 | pw -= a.deg(); 470 | auto mul = bpow(b.lead(), pw) * T((b.deg() & a.deg() & 1) ? -1 : 1); 471 | auto ans = resultant(b, a); 472 | return ans * mul; 473 | } 474 | } 475 | 476 | static poly_t xk(size_t n) { // P(x) = x^n 477 | return poly_t(T(1)).mul_xk(n); 478 | } 479 | 480 | static poly_t ones(size_t n) { // P(x) = 1 + x + ... + x^{n-1} 481 | return std::vector(n, 1); 482 | } 483 | 484 | static poly_t expx(size_t n) { // P(x) = e^x (mod x^n) 485 | return ones(n).borel(); 486 | } 487 | 488 | static poly_t log1px(size_t n) { // P(x) = log(1+x) (mod x^n) 489 | std::vector coeffs(n, 0); 490 | for(size_t i = 1; i < n; i++) { 491 | coeffs[i] = (i & 1 ? T(i).inv() : -T(i).inv()); 492 | } 493 | return coeffs; 494 | } 495 | 496 | static poly_t log1mx(size_t n) { // P(x) = log(1-x) (mod x^n) 497 | return -ones(n).integr(); 498 | } 499 | 500 | // [x^k] (a corr b) = sum_{i} a{(k-m)+i}*bi 501 | static poly_t corr(poly_t a, poly_t b) { // cross-correlation 502 | return a * b.reverse(); 503 | } 504 | 505 | // [x^k] (a semicorr b) = sum_i a{i+k} * b{i} 506 | static poly_t semicorr(poly_t a, poly_t b) { 507 | return corr(a, b).div_xk(b.deg()); 508 | } 509 | 510 | poly_t invborel() const { // ak *= k! 511 | auto res = *this; 512 | for(int i = 0; i <= deg(); i++) { 513 | res.coef(i) *= fact(i); 514 | } 515 | return res; 516 | } 517 | 518 | poly_t borel() const { // ak /= k! 519 | auto res = *this; 520 | for(int i = 0; i <= deg(); i++) { 521 | res.coef(i) *= rfact(i); 522 | } 523 | return res; 524 | } 525 | 526 | poly_t shift(T a) const { // P(x + a) 527 | return semicorr(invborel(), expx(deg() + 1).mulx(a)).borel(); 528 | } 529 | 530 | poly_t x2() { // P(x) -> P(x^2) 531 | std::vector res(2 * a.size()); 532 | for(size_t i = 0; i < a.size(); i++) { 533 | res[2 * i] = a[i]; 534 | } 535 | return res; 536 | } 537 | 538 | // Return {P0, P1}, where P(x) = P0(x) + xP1(x) 539 | std::array bisect() const { 540 | std::vector res[2]; 541 | res[0].reserve(deg() / 2 + 1); 542 | res[1].reserve(deg() / 2 + 1); 543 | for(int i = 0; i <= deg(); i++) { 544 | res[i % 2].push_back(a[i]); 545 | } 546 | return {res[0], res[1]}; 547 | } 548 | 549 | // Find [x^k] P / Q 550 | static T kth_rec(poly_t P, poly_t Q, int64_t k) { 551 | while(k > Q.deg()) { 552 | int n = Q.a.size(); 553 | auto [Q0, Q1] = Q.mulx(-1).bisect(); 554 | auto [P0, P1] = P.bisect(); 555 | 556 | int N = fft::com_size((n + 1) / 2, (n + 1) / 2); 557 | 558 | auto Q0f = fft::dft(Q0.a, N); 559 | auto Q1f = fft::dft(Q1.a, N); 560 | auto P0f = fft::dft(P0.a, N); 561 | auto P1f = fft::dft(P1.a, N); 562 | 563 | if(k % 2) { 564 | P = poly_t(Q0f * P1f) + poly_t(Q1f * P0f); 565 | } else { 566 | P = poly_t(Q0f * P0f) + poly_t(Q1f * P1f).mul_xk(1); 567 | } 568 | Q = poly_t(Q0f * Q0f) - poly_t(Q1f * Q1f).mul_xk(1); 569 | k /= 2; 570 | } 571 | return (P * Q.inv(Q.deg() + 1))[k]; 572 | } 573 | 574 | // inverse series mod x^n 575 | poly_t inv(size_t n) const { 576 | return poly::impl::inv(*this, n); 577 | } 578 | // [x^k]..[x^{k+n-1}] of inv() 579 | // supports negative k if k+n >= 0 580 | poly_t inv(int64_t k, size_t n) const { 581 | return poly::impl::inv(*this, k, n); 582 | } 583 | 584 | // compute A(B(x)) mod x^n in O(n^2) 585 | static poly_t compose(poly_t A, poly_t B, int n) { 586 | int q = std::sqrt(n); 587 | std::vector Bk(q); 588 | auto Bq = B.pow(q, n); 589 | Bk[0] = poly_t(T(1)); 590 | for(int i = 1; i < q; i++) { 591 | Bk[i] = (Bk[i - 1] * B).mod_xk(n); 592 | } 593 | poly_t Bqk(1); 594 | poly_t ans; 595 | for(int i = 0; i <= n / q; i++) { 596 | poly_t cur; 597 | for(int j = 0; j < q; j++) { 598 | cur += Bk[j] * A[i * q + j]; 599 | } 600 | ans += (Bqk * cur).mod_xk(n); 601 | Bqk = (Bqk * Bq).mod_xk(n); 602 | } 603 | return ans; 604 | } 605 | 606 | // compute A(B(x)) mod x^n in O(sqrt(pqn log^3 n)) 607 | // preferrable when p = deg A and q = deg B 608 | // are much less than n 609 | static poly_t compose_large(poly_t A, poly_t B, int n) { 610 | if(B[0] != T(0)) { 611 | return compose_large(A.shift(B[0]), B - B[0], n); 612 | } 613 | 614 | int q = std::sqrt(n); 615 | auto [B0, B1] = std::make_pair(B.mod_xk(q), B.div_xk(q)); 616 | 617 | B0 = B0.div_xk(1); 618 | std::vector pw(A.deg() + 1); 619 | auto getpow = [&](int k) { 620 | return pw[k].is_zero() ? pw[k] = B0.pow(k, n - k) : pw[k]; 621 | }; 622 | 623 | std::function compose_dac = [&getpow, &compose_dac](poly_t const& f, int m, int N) { 624 | if(f.deg() <= 0) { 625 | return f; 626 | } 627 | int k = m / 2; 628 | auto [f0, f1] = std::make_pair(f.mod_xk(k), f.div_xk(k)); 629 | auto [A, B] = std::make_pair(compose_dac(f0, k, N), compose_dac(f1, m - k, N - k)); 630 | return (A + (B.mod_xk(N - k) * getpow(k).mod_xk(N - k)).mul_xk(k)).mod_xk(N); 631 | }; 632 | 633 | int r = n / q; 634 | auto Ar = A.deriv(r); 635 | auto AB0 = compose_dac(Ar, Ar.deg() + 1, n); 636 | 637 | auto Bd = B0.mul_xk(1).deriv(); 638 | 639 | poly_t ans = T(0); 640 | 641 | std::vector B1p(r + 1); 642 | B1p[0] = poly_t(T(1)); 643 | for(int i = 1; i <= r; i++) { 644 | B1p[i] = (B1p[i - 1] * B1.mod_xk(n - i * q)).mod_xk(n - i * q); 645 | } 646 | while(r >= 0) { 647 | ans += (AB0.mod_xk(n - r * q) * rfact(r) * B1p[r]).mul_xk(r * q).mod_xk(n); 648 | r--; 649 | if(r >= 0) { 650 | AB0 = ((AB0 * Bd).integr() + A[r] * fact(r)).mod_xk(n); 651 | } 652 | } 653 | 654 | return ans; 655 | } 656 | }; 657 | 658 | static auto operator * (const auto& a, const poly_t& b) { 659 | return b * a; 660 | } 661 | }; 662 | #endif // CP_ALGO_ALGEBRA_POLY_HPP 663 | -------------------------------------------------------------------------------- /Prime Factorization/py_prime_factorization.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | def primesbelow(N): 4 | # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188 5 | #""" Input N>=6, Returns a list of primes, 2 <= p < N """ 6 | correction = N % 6 > 1 7 | N = {0:N, 1:N-1, 2:N+4, 3:N+3, 4:N+2, 5:N+1}[N%6] 8 | sieve = [True] * (N // 3) 9 | sieve[0] = False 10 | for i in range(int(N ** .5) // 3 + 1): 11 | if sieve[i]: 12 | k = (3 * i + 1) | 1 13 | sieve[k*k // 3::2*k] = [False] * ((N//6 - (k*k)//6 - 1)//k + 1) 14 | sieve[(k*k + 4*k - 2*k*(i%2)) // 3::2*k] = [False] * ((N // 6 - (k*k + 4*k - 2*k*(i%2))//6 - 1) // k + 1) 15 | return [2, 3] + [(3 * i + 1) | 1 for i in range(1, N//3 - correction) if sieve[i]] 16 | 17 | smallprimeset = set(primesbelow(100000)) 18 | _smallprimeset = 100000 19 | def isprime(n, precision=7): 20 | # http://en.wikipedia.org/wiki/Miller-Rabin_primality_test#Algorithm_and_running_time 21 | if n == 1 or n % 2 == 0: 22 | return False 23 | elif n < 1: 24 | raise ValueError("Out of bounds, first argument must be > 0") 25 | elif n < _smallprimeset: 26 | return n in smallprimeset 27 | 28 | 29 | d = n - 1 30 | s = 0 31 | while d % 2 == 0: 32 | d //= 2 33 | s += 1 34 | 35 | for repeat in range(precision): 36 | a = random.randrange(2, n - 2) 37 | x = pow(a, d, n) 38 | 39 | if x == 1 or x == n - 1: continue 40 | 41 | for r in range(s - 1): 42 | x = pow(x, 2, n) 43 | if x == 1: return False 44 | if x == n - 1: break 45 | else: return False 46 | 47 | return True 48 | 49 | # https://comeoncodeon.wordpress.com/2010/09/18/pollard-rho-brent-integer-factorization/ 50 | def pollard_brent(n): 51 | if n % 2 == 0: return 2 52 | if n % 3 == 0: return 3 53 | 54 | y, c, m = random.randint(1, n-1), random.randint(1, n-1), random.randint(1, n-1) 55 | g, r, q = 1, 1, 1 56 | while g == 1: 57 | x = y 58 | for i in range(r): 59 | y = (pow(y, 2, n) + c) % n 60 | 61 | k = 0 62 | while k < r and g==1: 63 | ys = y 64 | for i in range(min(m, r-k)): 65 | y = (pow(y, 2, n) + c) % n 66 | q = q * abs(x-y) % n 67 | g = gcd(q, n) 68 | k += m 69 | r *= 2 70 | if g == n: 71 | while True: 72 | ys = (pow(ys, 2, n) + c) % n 73 | g = gcd(abs(x - ys), n) 74 | if g > 1: 75 | break 76 | 77 | return g 78 | 79 | smallprimes = primesbelow(1000) # might seem low, but 1000*1000 = 1000000, so this will fully factor every composite < 1000000 80 | def primefactors(n, sort=False): 81 | factors = [] 82 | 83 | limit = int(n ** .5) + 1 84 | for checker in smallprimes: 85 | if checker > limit: break 86 | while n % checker == 0: 87 | factors.append(checker) 88 | n //= checker 89 | limit = int(n ** .5) + 1 90 | if checker > limit: break 91 | 92 | if n < 2: return factors 93 | 94 | while n > 1: 95 | if isprime(n): 96 | factors.append(n) 97 | break 98 | factor = pollard_brent(n) # trial division did not fully factor, switch to pollard-brent 99 | factors.extend(primefactors(factor)) # recurse to factor the not necessarily prime factor returned by pollard-brent 100 | n //= factor 101 | 102 | if sort: factors.sort() 103 | 104 | return factors 105 | 106 | def factorization(n): 107 | factors = {} 108 | for p1 in primefactors(n): 109 | try: 110 | factors[p1] += 1 111 | except KeyError: 112 | factors[p1] = 1 113 | return factors 114 | 115 | totients = {} 116 | def totient(n): 117 | if n == 0: return 1 118 | 119 | try: return totients[n] 120 | except KeyError: pass 121 | 122 | tot = 1 123 | for p, exp in factorization(n).items(): 124 | tot *= (p - 1) * p ** (exp - 1) 125 | 126 | totients[n] = tot 127 | return tot 128 | 129 | def gcd(a, b): 130 | if a == b: return a 131 | while b > 0: a, b = b, a % b 132 | return a 133 | 134 | def lcm(a, b): 135 | return abs(a * b) // gcd(a, b) 136 | 137 | 138 | # Function calling and input begins here 139 | n = long(raw_input()) 140 | d = factorization(n) 141 | print d 142 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data-Structures-and-Algorithms 2 | A collection of some implementations of data structures and algorithms, primarily for competitive programming. 3 | 4 | Hello, world! This effort is directed towards making a compilation of some interesting data structures and algorithms, for the community to learn, collaborate and refer whenever required. 5 | 6 | In the coming months, I hope to have a variety of data structures and algorithms here. 7 | 8 | Feel free to create PRs and issues on the repo. 9 | 10 | Report bugs/issues/suggestions to xennygrimmato (vstulsyan@gmail.com) 11 | 12 | Please read [CONTRIBUTING.md](CONTRIBUTING.md) for contribution instructions. 13 | -------------------------------------------------------------------------------- /Rabin Miller Primality Test/rabin_miller.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | #define s(n) scanf("%lld",&n) 13 | #define sc(n) scanf("%c",&n) 14 | #define sl(n) scanf("%lld",&n) 15 | #define sf(n) scanf("%Lf",&n) 16 | #define ss(n) scanf("%s",n) 17 | #define maX(a,b) ( (a) > (b) ? (a) : (b)) 18 | // Useful constants 19 | #define INF (int)1e9 20 | #define EPS 1e-9 21 | 22 | // Useful hardware instructions 23 | #define bitcount __builtin_popcount 24 | #define gcd __gcd 25 | 26 | // Useful container manipulation / traversal macros 27 | #define forall(i,a,b) for(long long i=a;i0)return a; 43 | return -a; 44 | } 45 | 46 | typedef long long ULL; 47 | 48 | ULL mulmod(ULL a, ULL b, ULL c){ 49 | ULL x = 0,y = a%c; 50 | 51 | while(b>0){ 52 | if(b&1) x = (x+y)%c; 53 | y = (y<<1)%c; 54 | b >>= 1; 55 | } 56 | 57 | return x; 58 | } 59 | 60 | ULL pow(ULL a, ULL b, ULL c){ 61 | ULL x = 1, y = a; 62 | 63 | while(b>0){ 64 | if(b&1) x = mulmod(x,y,c); 65 | y = mulmod(y,y,c); 66 | b >>= 1; 67 | } 68 | 69 | return x; 70 | } 71 | 72 | bool isPrime(ULL p, int it){ 73 | if(p<2) return false; 74 | if(p==2) return true; 75 | if((p&1)==0) return false; 76 | 77 | ULL s = p-1; 78 | while(s%2==0) s >>= 1; 79 | 80 | while(it--){ 81 | ULL a = rand()%(p-1)+1,temp = s; 82 | ULL mod = pow(a,temp,p); 83 | 84 | if(mod==-1 || mod==1) continue; 85 | 86 | while(temp!=p-1 && mod!=p-1){ 87 | mod = mulmod(mod,mod,p); 88 | temp <<= 1; 89 | } 90 | 91 | if(mod!=p-1) return false; 92 | } 93 | 94 | return true; 95 | } 96 | 97 | 98 | 99 | int main() 100 | { 101 | ULL test,n; 102 | test=10000; 103 | s(test); 104 | forall(i,0,test) 105 | { 106 | s(n); 107 | {if(isPrime(n,5)) 108 | printf("%lld\n",n); 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /Range Max in Window/rmq_fixed_window.cpp: -------------------------------------------------------------------------------- 1 | // Sample AC submission: https://codeforces.com/contest/1731/submission/186979283 2 | 3 | // 1D Problem: You are given an array of numbers A[] of size n and a number k ≤ n. Find the minimum value for each continuous subarray of size k. 4 | // 2D Problem: You are given an matrix of numbers A[][] of size n × m and two numbers k ≤ n, l ≤ m. Find the minimum value for each continuous submatrix of size k × l. 5 | // Blog: https://codeforces.com/blog/entry/53810 6 | 7 | // Source: https://codeforces.com/blog/entry/53810?#comment-871637 8 | // Sample problem: https://atcoder.jp/contests/abc228/tasks/abc228_f 9 | 10 | template 11 | vector get_window_maxs_1d(const vector& a, int k) { 12 | const int n = a.size(); 13 | vector b(n - k + 1); 14 | deque mono; 15 | for (int i = 0; i < n; ++i) { 16 | while (!mono.empty() && a[mono.back()] <= a[i]) { 17 | mono.pop_back(); 18 | } 19 | mono.push_back(i); 20 | if (mono.front() <= i - k) { 21 | mono.pop_front(); 22 | } 23 | if (i + 1 >= k) { 24 | b[i + 1 - k] = a[mono.front()]; 25 | } 26 | } 27 | return b; 28 | } 29 | 30 | template 31 | vector> get_window_maxs_2d(const vector>& a, int k, int l) { 32 | const int n = a.size(), m = a[0].size(); 33 | vector> b(m - l + 1, vector(n)); 34 | for (int i = 0; i < n; ++i) { 35 | const auto tmp = get_window_maxs_1d(a[i], l); 36 | for (int j = 0; j < m - l + 1; ++j) { 37 | b[j][i] = tmp[j]; 38 | } 39 | } 40 | vector> c(n - k + 1, vector(m - l + 1)); 41 | for (int j = 0; j < m - l + 1; ++j) { 42 | const auto tmp = get_window_maxs_1d(b[j], k); 43 | for (int i = 0; i < n - k + 1; ++i) { 44 | c[i][j] = tmp[i]; 45 | } 46 | } 47 | return c; 48 | } 49 | -------------------------------------------------------------------------------- /ReedsSloane/koosaga_reedssloane.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using lint = long long; 4 | 5 | struct LinearRecurrence { 6 | using ll = long long; 7 | using vec = vector; 8 | 9 | static void extand(vec &a, ll d, ll value = 0) { 10 | if (d <= a.size()) return; 11 | a.resize(d, value); 12 | } 13 | 14 | static vec BerlekampMassey(const vec &s, ll mod) { 15 | std::function inverse = [&](ll a) { 16 | return a == 1 ? 1 : (ll)(mod - mod / a) * inverse(mod % a) % mod; 17 | }; 18 | vec A = {1}, B = {1}; 19 | ll b = s[0]; 20 | for (size_t i = 1, m = 1; i < s.size(); ++i, m++) { 21 | ll d = 0; 22 | for (size_t j = 0; j < A.size(); ++j) { 23 | d += A[j] * s[i - j] % mod; 24 | } 25 | if (!(d %= mod)) continue; 26 | if (2 * (A.size() - 1) <= i) { 27 | auto temp = A; 28 | extand(A, B.size() + m); 29 | ll coef = d * inverse(b) % mod; 30 | for (size_t j = 0; j < B.size(); ++j) { 31 | A[j + m] -= coef * B[j] % mod; 32 | if (A[j + m] < 0) A[j + m] += mod; 33 | } 34 | B = temp, b = d, m = 0; 35 | } else { 36 | extand(A, B.size() + m); 37 | ll coef = d * inverse(b) % mod; 38 | for (size_t j = 0; j < B.size(); ++j) { 39 | A[j + m] -= coef * B[j] % mod; 40 | if (A[j + m] < 0) A[j + m] += mod; 41 | } 42 | } 43 | } 44 | return A; 45 | } 46 | 47 | static void exgcd(ll a, ll b, ll &g, ll &x, ll &y) { 48 | if (!b) x = 1, y = 0, g = a; 49 | else { 50 | exgcd(b, a % b, g, y, x); 51 | y -= x * (a / b); 52 | } 53 | } 54 | static ll crt(const vec &c, const vec &m) { 55 | ll n = c.size(); 56 | ll M = 1, ans = 0; 57 | for (ll i = 0; i < n; ++i) M *= m[i]; 58 | for (ll i = 0; i < n; ++i) { 59 | ll x, y, g, tm = M / m[i]; 60 | exgcd(tm, m[i], g, x, y); 61 | ans = (ans + tm * x * c[i] % M) % M; 62 | } 63 | return (ans + M) % M; 64 | } 65 | static vec ReedsSloane(const vec &s, ll mod) { 66 | auto inverse = [] (ll a, ll m) { 67 | ll d, x, y; 68 | exgcd(a, m, d, x, y); 69 | return d == 1 ? (x % m + m) % m : -1; 70 | }; 71 | auto L = [] (const vec &a, const vec &b) { 72 | ll da = (a.size() > 1 || (a.size() == 1 && a[0])) ? (ll)a.size() - 1 : -1000; 73 | ll db = (b.size() > 1 || (b.size() == 1 && b[0])) ? (ll)b.size() - 1 : -1000; 74 | return max(da, db + 1); 75 | }; 76 | auto prime_power = [&] (const vec &s, ll mod, ll p, ll e) { 77 | // linear feedback shift register mod p^e, p is prime 78 | vector a(e), b(e), an(e), bn(e), ao(e), bo(e); 79 | vec t(e), u(e), r(e), to(e, 1), uo(e), pw(e + 1);; 80 | 81 | pw[0] = 1; 82 | for (ll i = pw[0] = 1; i <= e; ++i) pw[i] = pw[i - 1] * p; 83 | for (ll i = 0; i < e; ++i) { 84 | a[i] = {pw[i]}, an[i] = {pw[i]}; 85 | b[i] = {0}, bn[i] = {s[0] * pw[i] % mod}; 86 | t[i] = s[0] * pw[i] % mod; 87 | if (t[i] == 0) { 88 | t[i] = 1, u[i] = e; 89 | } else { 90 | for (u[i] = 0; t[i] % p == 0; t[i] /= p, ++u[i]); 91 | } 92 | } 93 | for (ll k = 1; k < s.size(); ++k) { 94 | for (ll g = 0; g < e; ++g) { 95 | if (L(an[g], bn[g]) > L(a[g], b[g])) { 96 | ao[g] = a[e - 1 - u[g]]; 97 | bo[g] = b[e - 1 - u[g]]; 98 | to[g] = t[e - 1 - u[g]]; 99 | uo[g] = u[e - 1 - u[g]]; 100 | r[g] = k - 1; 101 | } 102 | } 103 | a = an, b = bn; 104 | for (ll o = 0; o < e; ++o) { 105 | ll d = 0; 106 | for (ll i = 0; i < a[o].size() && i <= k; ++i) { 107 | d = (d + a[o][i] * s[k - i]) % mod; 108 | } 109 | if (d == 0) { 110 | t[o] = 1, u[o] = e; 111 | } else { 112 | for (u[o] = 0, t[o] = d; t[o] % p == 0; t[o] /= p, ++u[o]); 113 | ll g = e - 1 - u[o]; 114 | if (L(a[g], b[g]) == 0) { 115 | extand(bn[o], k + 1); 116 | bn[o][k] = (bn[o][k] + d) % mod; 117 | } else { 118 | ll coef = t[o] * inverse(to[g], mod) % mod * pw[u[o] - uo[g]] % mod; 119 | ll m = k - r[g]; 120 | extand(an[o], ao[g].size() + m); 121 | extand(bn[o], bo[g].size() + m); 122 | for (ll i = 0; i < ao[g].size(); ++i) { 123 | an[o][i + m] -= coef * ao[g][i] % mod; 124 | if (an[o][i + m] < 0) an[o][i + m] += mod; 125 | } 126 | while (an[o].size() && an[o].back() == 0) an[o].pop_back(); 127 | for (ll i = 0; i < bo[g].size(); ++i) { 128 | bn[o][i + m] -= coef * bo[g][i] % mod; 129 | if (bn[o][i + m] < 0) bn[o][i + m] -= mod; 130 | } 131 | while (bn[o].size() && bn[o].back() == 0) bn[o].pop_back(); 132 | } 133 | } 134 | } 135 | } 136 | return make_pair(an[0], bn[0]); 137 | }; 138 | 139 | vector> fac; 140 | for (ll i = 2; i * i <= mod; ++i) if (mod % i == 0) { 141 | ll cnt = 0, pw = 1; 142 | while (mod % i == 0) mod /= i, ++cnt, pw *= i; 143 | fac.emplace_back(pw, i, cnt); 144 | } 145 | if (mod > 1) fac.emplace_back(mod, mod, 1); 146 | vector as; 147 | ll n = 0; 148 | for (auto &&x: fac) { 149 | ll mod, p, e; 150 | vec a, b; 151 | tie(mod, p, e) = x; 152 | auto ss = s; 153 | for (auto &&x: ss) x %= mod; 154 | tie(a, b) = prime_power(ss, mod, p, e); 155 | as.emplace_back(a); 156 | n = max(n, (ll) a.size()); 157 | } 158 | vec a(n), c(as.size()), m(as.size()); 159 | 160 | for (ll i = 0; i < n; ++i) { 161 | for (ll j = 0; j < as.size(); ++j) { 162 | m[j] = get<0>(fac[j]); 163 | c[j] = i < as[j].size() ? as[j][i] : 0; 164 | } 165 | a[i] = crt(c, m); 166 | } 167 | return a; 168 | } 169 | 170 | LinearRecurrence(const vec &s, const vec &c, ll mod): 171 | init(s), trans(c), mod(mod), m(s.size()) {} 172 | 173 | LinearRecurrence(const vec &s, ll mod, bool is_prime = true): mod(mod) { 174 | vec A; 175 | if(is_prime) A = BerlekampMassey(s,mod); 176 | else A = ReedsSloane(s, mod); 177 | if (A.empty()) A = {0}; 178 | m = A.size() - 1; 179 | 180 | trans.resize(m); 181 | for (ll i = 0; i < m; ++i) { 182 | trans[i] = (mod - A[i + 1]) % mod; 183 | } 184 | init = {s.begin(), s.begin() + m}; 185 | } 186 | int get_nth(unsigned long long n){ 187 | int m = trans.size(); 188 | vector s(m), t(m); 189 | s[0] = 1; 190 | if(m != 1) t[1] = 1; 191 | else t[0] = trans[0]; 192 | auto mul = [&](vector v, vector w){ 193 | int m = v.size(); 194 | vector t(2 * m); 195 | for(int j=0; j= mod) t[j+k] -= mod; 199 | } 200 | } 201 | for(int j=2*m-1; j>=m; j--){ 202 | for(int k=1; k<=m; k++){ 203 | t[j-k] += 1ll * t[j] * trans[k-1] % mod; 204 | if(t[j-k] >= mod) t[j-k] -= mod; 205 | } 206 | } 207 | t.resize(m); 208 | return t; 209 | }; 210 | while(n){ 211 | if(n & 1) s = mul(s, t); 212 | t = mul(t, t); 213 | n >>= 1; 214 | } 215 | lint ret = 0; 216 | for(int i=0; i> n; 235 | vector v(L, L + MAXN); 236 | LinearRecurrence reeds_sloane(v, mod, 0); 237 | lint ans = reeds_sloane.get_nth(n); 238 | printf("%09lld", ans); 239 | } 240 | -------------------------------------------------------------------------------- /ReedsSloane/zimpha_linear_recurrence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // 1. Given first m items init[0..m-1] and coefficents trans[0..m-1] 9 | // 10 | // ```cpp 11 | // std::vector init = {1, 1}; 12 | // std::vector trans = {1, 1}; 13 | // const int mod = 1e9 + 7; // 998244353; 1000000006; 14 | // LinearRecurrence lr{init, trans, mod}; 15 | // std::cout << lr.calc(1000000000000000000ll) << std::endl; 16 | // ``` 17 | // 18 | // 2. Given first 2 * m items init[0..2m-1], it will compute trans[0..m-1] 19 | // trans[0..m] will be given as that: 20 | // init[m] = sum_{i=0}^{m-1} init[i] * trans[i] 21 | // you should make sure that init[0] is not zero and init[i] is in [0, mod - 1] 22 | // 23 | // ```cpp 24 | // std::vector init = {1, 1, 2, 3, 5, 8, 13}; 25 | // const int prime_mod = 998244353; 26 | // LinearRecurrence lr1{init, prime_mod}; 27 | // std::cout << lr.calc(1000000000000000000ll) << std::endl; 28 | // const int non_prime_mod = 1000000006; 29 | // LinearRecurrence lr2{init, non_prime_mod, false}; 30 | // std::cout << lr.calc(1000000000000000000ll) << std::endl; 31 | // ``` 32 | struct LinearRecurrence { 33 | using int64 = long long; 34 | using vec = std::vector; 35 | 36 | static void extend(vec &a, size_t d, int64 value = 0) { 37 | if (d <= a.size()) return; 38 | a.resize(d, value); 39 | } 40 | static vec BerlekampMassey(const vec &s, int64 mod) { 41 | std::function inverse = [&](int64 a) { 42 | return a == 1 ? 1 : (int64)(mod - mod / a) * inverse(mod % a) % mod; 43 | }; 44 | vec A = {1}, B = {1}; 45 | int64 b = s[0]; 46 | assert(b != 0); 47 | for (size_t i = 1, m = 1; i < s.size(); ++i, m++) { 48 | int64 d = 0; 49 | for (size_t j = 0; j < A.size(); ++j) { 50 | d += A[j] * s[i - j] % mod; 51 | } 52 | if (!(d %= mod)) continue; 53 | if (2 * (A.size() - 1) <= i) { 54 | auto temp = A; 55 | extend(A, B.size() + m); 56 | int64 coef = d * inverse(b) % mod; 57 | for (size_t j = 0; j < B.size(); ++j) { 58 | A[j + m] -= coef * B[j] % mod; 59 | if (A[j + m] < 0) A[j + m] += mod; 60 | } 61 | B = temp, b = d, m = 0; 62 | } else { 63 | extend(A, B.size() + m); 64 | int64 coef = d * inverse(b) % mod; 65 | for (size_t j = 0; j < B.size(); ++j) { 66 | A[j + m] -= coef * B[j] % mod; 67 | if (A[j + m] < 0) A[j + m] += mod; 68 | } 69 | } 70 | } 71 | return A; 72 | } 73 | static void exgcd(int64 a, int64 b, int64 &g, int64 &x, int64 &y) { 74 | if (!b) x = 1, y = 0, g = a; 75 | else { 76 | exgcd(b, a % b, g, y, x); 77 | y -= x * (a / b); 78 | } 79 | } 80 | static int64 crt(const vec &c, const vec &m) { 81 | int n = c.size(); 82 | int64 M = 1, ans = 0; 83 | for (int i = 0; i < n; ++i) M *= m[i]; 84 | for (int i = 0; i < n; ++i) { 85 | int64 x, y, g, tm = M / m[i]; 86 | exgcd(tm, m[i], g, x, y); 87 | ans = (ans + tm * x * c[i] % M) % M; 88 | } 89 | return (ans + M) % M; 90 | } 91 | static vec ReedsSloane(const vec &s, int64 mod) { 92 | auto inverse = [] (int64 a, int64 m) { 93 | int64 d, x, y; 94 | exgcd(a, m, d, x, y); 95 | return d == 1 ? (x % m + m) % m : -1; 96 | }; 97 | auto L = [] (const vec &a, const vec &b) { 98 | int da = (a.size() > 1 || (a.size() == 1 && a[0])) ? a.size() - 1 : -1000; 99 | int db = (b.size() > 1 || (b.size() == 1 && b[0])) ? b.size() - 1 : -1000; 100 | return std::max(da, db + 1); 101 | }; 102 | auto prime_power = [&] (const vec &s, int64 mod, int64 p, int64 e) { 103 | // linear feedback shift register mod p^e, p is prime 104 | std::vector a(e), b(e), an(e), bn(e), ao(e), bo(e); 105 | vec t(e), u(e), r(e), to(e, 1), uo(e), pw(e + 1, 1);; 106 | for (int i = 1; i <= e; ++i) { 107 | pw[i] = pw[i - 1] * p; 108 | assert(pw[i] <= mod); 109 | } 110 | for (int64 i = 0; i < e; ++i) { 111 | a[i] = {pw[i]}, an[i] = {pw[i]}; 112 | b[i] = {0}, bn[i] = {s[0] * pw[i] % mod}; 113 | t[i] = s[0] * pw[i] % mod; 114 | if (t[i] == 0) { 115 | t[i] = 1, u[i] = e; 116 | } else { 117 | for (u[i] = 0; t[i] % p == 0; t[i] /= p, ++u[i]); 118 | } 119 | } 120 | for (size_t k = 1; k < s.size(); ++k) { 121 | for (int g = 0; g < e; ++g) { 122 | if (L(an[g], bn[g]) > L(a[g], b[g])) { 123 | ao[g] = a[e - 1 - u[g]]; 124 | bo[g] = b[e - 1 - u[g]]; 125 | to[g] = t[e - 1 - u[g]]; 126 | uo[g] = u[e - 1 - u[g]]; 127 | r[g] = k - 1; 128 | } 129 | } 130 | a = an, b = bn; 131 | for (int o = 0; o < e; ++o) { 132 | int64 d = 0; 133 | for (size_t i = 0; i < a[o].size() && i <= k; ++i) { 134 | d = (d + a[o][i] * s[k - i]) % mod; 135 | } 136 | if (d == 0) { 137 | t[o] = 1, u[o] = e; 138 | } else { 139 | for (u[o] = 0, t[o] = d; t[o] % p == 0; t[o] /= p, ++u[o]); 140 | int g = e - 1 - u[o]; 141 | if (L(a[g], b[g]) == 0) { 142 | extend(bn[o], k + 1); 143 | bn[o][k] = (bn[o][k] + d) % mod; 144 | } else { 145 | int64 coef = t[o] * inverse(to[g], mod) % mod * pw[u[o] - uo[g]] % mod; 146 | int m = k - r[g]; 147 | assert(m >= 0); 148 | extend(an[o], ao[g].size() + m); 149 | extend(bn[o], bo[g].size() + m); 150 | for (size_t i = 0; i < ao[g].size(); ++i) { 151 | an[o][i + m] -= coef * ao[g][i] % mod; 152 | if (an[o][i + m] < 0) an[o][i + m] += mod; 153 | } 154 | while (an[o].size() && an[o].back() == 0) an[o].pop_back(); 155 | for (size_t i = 0; i < bo[g].size(); ++i) { 156 | bn[o][i + m] -= coef * bo[g][i] % mod; 157 | if (bn[o][i + m] < 0) bn[o][i + m] -= mod; 158 | } 159 | while (bn[o].size() && bn[o].back() == 0) bn[o].pop_back(); 160 | } 161 | } 162 | } 163 | } 164 | return std::make_pair(an[0], bn[0]); 165 | }; 166 | 167 | std::vector> fac; 168 | for (int64 i = 2; i * i <= mod; ++i) if (mod % i == 0) { 169 | int64 cnt = 0, pw = 1; 170 | while (mod % i == 0) mod /= i, ++cnt, pw *= i; 171 | fac.emplace_back(pw, i, cnt); 172 | } 173 | if (mod > 1) fac.emplace_back(mod, mod, 1); 174 | std::vector as; 175 | size_t n = 0; 176 | for (auto &&x: fac) { 177 | int64 mod, p, e; 178 | vec a, b; 179 | std::tie(mod, p, e) = x; 180 | auto ss = s; 181 | for (auto &&x: ss) x %= mod; 182 | std::tie(a, b) = prime_power(ss, mod, p, e); 183 | as.emplace_back(a); 184 | n = std::max(n, a.size()); 185 | } 186 | vec a(n), c(as.size()), m(as.size()); 187 | for (size_t i = 0; i < n; ++i) { 188 | for (size_t j = 0; j < as.size(); ++j) { 189 | m[j] = std::get<0>(fac[j]); 190 | c[j] = i < as[j].size() ? as[j][i] : 0; 191 | } 192 | a[i] = crt(c, m); 193 | } 194 | return a; 195 | } 196 | 197 | LinearRecurrence(const vec &s, const vec &c, int64 mod): 198 | init(s), trans(c), mod(mod), m(s.size()) {} 199 | LinearRecurrence(const vec &s, int64 mod, bool is_prime = true): mod(mod) { 200 | assert(s.size() % 2 == 0); 201 | vec A; 202 | if (is_prime) A = BerlekampMassey(s, mod); 203 | else A = ReedsSloane(s, mod); 204 | m = s.size() / 2; 205 | A.resize(m + 1, 0); 206 | trans.resize(m); 207 | for (int i = 0; i < m; ++i) { 208 | trans[i] = (mod - A[i + 1]) % mod; 209 | } 210 | if (m == 0) m = 1, trans = {1}; 211 | std::reverse(trans.begin(), trans.end()); 212 | init = {s.begin(), s.begin() + m}; 213 | } 214 | int64 calc(int64 n) { 215 | if (mod == 1) return 0; 216 | if (n < m) return init[n]; 217 | vec v(m), u(m << 1); 218 | int64 msk = !!n; 219 | for (int64 m = n; m > 1; m >>= 1) msk <<= 1; 220 | v[0] = 1 % mod; 221 | for (int64 x = 0; msk; msk >>= 1, x <<= 1) { 222 | std::fill_n(u.begin(), m * 2, 0); 223 | x |= !!(n & msk); 224 | if (x < m) u[x] = 1 % mod; 225 | else {// can be optimized by fft/ntt 226 | for (int i = 0; i < m; ++i) { 227 | for (int j = 0, t = i + (x & 1); j < m; ++j, ++t) { 228 | u[t] = (u[t] + v[i] * v[j]) % mod; 229 | } 230 | } 231 | for (int i = m * 2 - 1; i >= m; --i) { 232 | for (int j = 0, t = i - m; j < m; ++j, ++t) { 233 | u[t] = (u[t] + trans[j] * u[i]) % mod; 234 | } 235 | } 236 | } 237 | v = {u.begin(), u.begin() + m}; 238 | } 239 | int64 ret = 0; 240 | for (int i = 0; i < m; ++i) { 241 | ret = (ret + v[i] * init[i]) % mod; 242 | } 243 | return ret; 244 | } 245 | 246 | vec init, trans; 247 | int64 mod; 248 | int m; 249 | }; 250 | 251 | void verify() { 252 | using int64 = long long; 253 | std::mt19937 gen{0}; 254 | for (int cas = 1; cas <= 1000; ++cas) { 255 | std::uniform_int_distribution dis_mod(1, 1 << 31); 256 | std::uniform_int_distribution dis_n(1, 100); 257 | int n = dis_n(gen), mod = dis_mod(gen); 258 | std::uniform_int_distribution dis_a(0, mod - 1); 259 | std::vector a(n), c(n); 260 | for (int i = 0; i < n; ++i) { 261 | a[i] = dis_a(gen); 262 | c[i] = dis_a(gen); 263 | } 264 | for (int i = n; i <= n * 2; ++i) { 265 | int64 sum = 0; 266 | for (int j = 0; j < n; ++j) { 267 | sum += c[j] * a[i - 1 - j] % mod; 268 | } 269 | a.push_back(sum % mod); 270 | } 271 | auto u = a.back(); a.pop_back(); 272 | LinearRecurrence lr{a, mod, false}; 273 | a.push_back(u); 274 | for (size_t i = 0; i < a.size(); ++i) { 275 | assert(lr.calc(i) == a[i]); 276 | } 277 | } 278 | } 279 | 280 | // http://www.spoj.com/problems/FINDLR/ 281 | void solve() { 282 | int T; 283 | scanf("%d", &T); 284 | for (int cas = 1; cas <= T; ++cas) { 285 | int n, mod; 286 | scanf("%d%d", &n, &mod); 287 | std::vector a(n * 2); 288 | for (int i = 0; i < n * 2; ++i) scanf("%lld", &a[i]); 289 | LinearRecurrence lr{a, mod, false}; 290 | printf("%lld\n", lr.calc(n * 2)); 291 | } 292 | } 293 | 294 | int main() { 295 | verify(); 296 | //solve(); 297 | return 0; 298 | } 299 | -------------------------------------------------------------------------------- /Segment Tree/MergeMethodAsTemplateArg.cpp: -------------------------------------------------------------------------------- 1 | // Source: https://codeforces.com/contest/1436/submission/96572644 2 | // Was looking for a Segtree template to which I can pass something like `[&](int x, int y) {return min(x, y);}` 3 | // to create a segment tree. 4 | // Also, build, query and update are all iterative. 5 | // Credits to tute7627 (https://codeforces.com/profile/tute7627). 6 | 7 | //#define _GLIBCXX_DEBUG 8 | 9 | #include 10 | using namespace std; 11 | 12 | #define endl '\n' 13 | #define lfs cout<= (ll)(n); i--) 25 | using ll = long long; 26 | using ld = long double; 27 | const ll MOD1 = 1e9+7; 28 | const ll MOD9 = 998244353; 29 | const ll INF = 1e18; 30 | using P = pair; 31 | templatebool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;} 32 | templatebool chmax(T1 &a,T2 b){if(avoid ans(bool x,T1 y,T2 z){if(x)cout<void debug(vector>&v,ll h,ll w){for(ll i=0;i&v,ll h,ll w){for(ll i=0;ivoid debug(vector&v,ll n){if(n!=0)cout<vector>vec(ll x, ll y, T w){vector>v(x,vector(y,w));return v;} 42 | ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;} 43 | vectordx={1,-1,0,0,1,1,-1,-1};vectordy={0,0,1,-1,1,-1,1,-1}; 44 | templatevector make_v(size_t a,T b){return vector(a,b);} 45 | templateauto make_v(size_t a,Ts... ts){return vector(a,make_v(ts...));} 46 | templateostream &operator<<(ostream &os, const pair&p){return os << p.first << " " << p.second;} 47 | templateostream &operator<<(ostream &os, const vector &v){for(auto &z:v)os << z << " ";cout<<"|"; return os;} 48 | //mt19937 mt(chrono::steady_clock::now().time_since_epoch().count()); 49 | int popcount(ll x){return __builtin_popcountll(x);}; 50 | int poplow(ll x){return __builtin_ctzll(x);}; 51 | int pophigh(ll x){return 63 - __builtin_clzll(x);}; 52 | template< typename Monoid ,typename F> 53 | struct SegmentTree { 54 | int sz, n; 55 | vector< Monoid > seg; 56 | const F f; 57 | const Monoid M1; 58 | 59 | SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1), n(n){ 60 | sz = 1; 61 | while(sz < n) sz <<= 1; 62 | seg.assign(2 * sz, M1); 63 | } 64 | 65 | void set(int k, const Monoid &x) { 66 | seg[k + sz] = x; 67 | } 68 | 69 | void build() { 70 | for(int k = sz - 1; k > 0; k--) { 71 | seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]); 72 | } 73 | } 74 | 75 | void update(int k, const Monoid &x) { 76 | k += sz; 77 | seg[k] = x; 78 | while(k >>= 1) { 79 | seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]); 80 | } 81 | } 82 | 83 | Monoid query(int a, int b) { 84 | if(a>=b)return M1; 85 | Monoid L = M1, R = M1; 86 | for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) { 87 | if(a & 1) L = f(L, seg[a++]); 88 | if(b & 1) R = f(seg[--b], R); 89 | } 90 | return f(L, R); 91 | } 92 | 93 | Monoid operator[](const int &k) const { 94 | return seg[k + sz]; 95 | } 96 | 97 | template< typename C > 98 | int find_subtree(int a, const C &check, Monoid &M, bool type) { 99 | while(a < sz) { 100 | Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]); 101 | if(check(nxt)) a = 2 * a + type; 102 | else M = nxt, a = 2 * a + 1 - type; 103 | } 104 | return a - sz; 105 | } 106 | //[a,x]が条件を満たす最初のx,満たさなければ-1 107 | template< typename C > 108 | int find_first(int a, const C &check) { 109 | Monoid L = M1; 110 | if(a <= 0) { 111 | if(check(f(L, seg[1]))) return find_subtree(1, check, L, false); 112 | return -1; 113 | } 114 | int b = sz; 115 | for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) { 116 | if(a & 1) { 117 | Monoid nxt = f(L, seg[a]); 118 | if(check(nxt)) return find_subtree(a, check, L, false); 119 | L = nxt; 120 | ++a; 121 | } 122 | } 123 | return -1; 124 | } 125 | 126 | template< typename C > 127 | int find_last(int b, const C &check) { 128 | Monoid R = M1; 129 | if(b >= sz) { 130 | if(check(f(seg[1], R))) return find_subtree(1, check, R, true); 131 | return -1; 132 | } 133 | int a = sz; 134 | for(b += sz; a < b; a >>= 1, b >>= 1) { 135 | if(b & 1) { 136 | Monoid nxt = f(seg[--b], R); 137 | if(check(nxt)) return find_subtree(b, check, R, true); 138 | R = nxt; 139 | } 140 | } 141 | return -1; 142 | } 143 | void print(){ 144 | for(ll i=0;i>n; 154 | vectora(n); 155 | rep(i,0,n)cin>>a[i],a[i]--; 156 | auto ff=[&](ll x,ll y){return min(x,y);}; 157 | SegmentTreeseg(n+1,ff,LLONG_MAX); 158 | vectort(n+2); 159 | rep(i,0,n+1)seg.set(i,-1); 160 | seg.build(); 161 | rep(i,0,n){ 162 | ll mi=seg.query(0,a[i]); 163 | if(mi>seg[a[i]])t[a[i]]=true; 164 | seg.update(a[i],i); 165 | } 166 | rep(i,0,n+1){ 167 | ll mi=seg.query(0,i); 168 | //cout<seg[i])<seg[i])t[i]=true; 170 | } 171 | t[0]=false; 172 | rep(i,0,n){ 173 | if(a[i]!=0)t[0]=true; 174 | } 175 | rep(i,0,n+2){ 176 | if(!t[i]){ 177 | cout< 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | typedef long long LL; 8 | 9 | #define MAXN 100000 10 | #define INF INT_MAX 11 | #define NEG_INF INT_MIN 12 | 13 | int a[MAXN+1]; // a has 0-indexed elements 14 | 15 | struct node 16 | { 17 | int start, end, sum_val, max_val, min_val; 18 | }; 19 | 20 | 21 | /* 22 | * Segment Tree Class 23 | * Functions: 24 | * # Range minimum query 25 | * # Range maximum query 26 | * # Range sum query 27 | * # Range update 28 | */ 29 | 30 | class segtree 31 | { 32 | node tree[4*MAXN+1]; // tree is has 1-indexed nodes 33 | int N; 34 | public: 35 | segtree(int *a, int sz) 36 | { 37 | N=sz; 38 | build(1,0,N-1,a); // build(node_no, begin, end, array) 39 | } 40 | 41 | void build(int node, int begin, int end, int *a) 42 | { 43 | if(begin == end) 44 | { 45 | tree[node].min_val = a[begin]; 46 | tree[node].max_val = a[begin]; 47 | tree[node].sum_val = a[begin]; 48 | } 49 | else 50 | { 51 | int mid = floor((begin+end)/2); 52 | int lc = 2*node; 53 | int rc = 2*node + 1; 54 | build(lc, begin, mid, a); 55 | build(rc, mid+1, end, a); 56 | tree[node].min_val = min(tree[lc].min_val, tree[rc].min_val); 57 | tree[node].max_val = max(tree[lc].max_val, tree[rc].max_val); 58 | tree[node].sum_val = tree[lc].sum_val + tree[rc].sum_val; 59 | } 60 | tree[node].start = begin; 61 | tree[node].end = end; 62 | } 63 | 64 | int QMin(int node, int t_begin, int t_end, int a_begin, int a_end) 65 | { 66 | if(t_begin >= a_begin && t_end <= a_end) 67 | { 68 | return tree[node].min_val; 69 | } 70 | else 71 | { 72 | int mid = floor((t_begin + t_end)/2); 73 | int result = INF; // setting result to INF 74 | int lc = 2*node; 75 | int rc = 2*node+1; 76 | if(mid >= a_begin && t_begin <= a_end) 77 | { 78 | result = min(result, QMin(lc, t_begin, mid, a_begin, a_end)); 79 | } 80 | if(t_end >= a_begin && ((mid+1) <= a_end)) 81 | { 82 | result = min(result, QMin(rc, mid+1, t_end, a_begin, a_end)); 83 | } 84 | return result; 85 | } 86 | } 87 | 88 | int query_min(int x, int y) // x and y are 1-indexed 89 | { 90 | x--,y--; 91 | return QMin(1,0,N-1,x,y); 92 | } 93 | 94 | 95 | int QMax(int node, int t_begin, int t_end, int a_begin, int a_end) 96 | { 97 | if(t_begin >= a_begin && t_end <= a_end) 98 | { 99 | return tree[node].max_val; 100 | } 101 | else 102 | { 103 | int mid = floor((t_begin + t_end)/2); 104 | int result = NEG_INF; // setting result to -INF 105 | int lc = 2*node; 106 | int rc = 2*node+1; 107 | if(mid >= a_begin && t_begin <= a_end) 108 | { 109 | result = max(result, QMax(lc, t_begin, mid, a_begin, a_end)); 110 | } 111 | if(t_end >= a_begin && ((mid+1) <= a_end)) 112 | { 113 | result = max(result, QMax(rc, mid+1, t_end, a_begin, a_end)); 114 | } 115 | return result; 116 | } 117 | } 118 | 119 | int query_max(int x, int y) // x and y are 1-indexed 120 | { 121 | x--,y--; 122 | return QMax(1,0,N-1,x,y); 123 | } 124 | 125 | int QSum(int node, int t_begin, int t_end, int a_begin, int a_end) 126 | { 127 | if(t_begin >= a_begin && t_end <= a_end) 128 | { 129 | return tree[node].sum_val; 130 | } 131 | else 132 | { 133 | int mid = floor((t_begin + t_end)/2); 134 | int left=0; 135 | int right=0; 136 | int result=0; 137 | int lc = 2*node; 138 | int rc = 2*node+1; 139 | if(mid >= a_begin && t_begin <= a_end) 140 | { 141 | left = QSum(lc, t_begin, mid, a_begin, a_end); 142 | } 143 | if(t_end >= a_begin && ((mid+1) <= a_end)) 144 | { 145 | right = QSum(rc, mid+1, t_end, a_begin, a_end); 146 | } 147 | result = left + right; 148 | return result; 149 | } 150 | } 151 | 152 | int query_sum(int x, int y) // x and y are 1-indexed 153 | { 154 | x--,y--; 155 | return QSum(1,0,N-1,x,y); 156 | } 157 | 158 | void QUpd(int node, int begin, int end, int pos, int val) 159 | { 160 | if(begin == end) 161 | { 162 | tree[node].min_val = val; 163 | tree[node].max_val = val; 164 | tree[node].sum_val = val; 165 | } 166 | else 167 | { 168 | int mid = floor((begin+end)/2); 169 | int lc, rc; 170 | lc = 2*node; 171 | rc = 2*node + 1; 172 | if(pos <= mid) 173 | { 174 | QUpd(lc,begin,mid,pos,val); 175 | } 176 | else 177 | { 178 | QUpd(rc,mid+1,end,pos,val); 179 | } 180 | tree[node].min_val = min(tree[lc].min_val, tree[rc].min_val); 181 | tree[node].max_val = max(tree[lc].max_val, tree[rc].max_val); 182 | tree[node].sum_val = tree[lc].sum_val + tree[rc].sum_val; 183 | } 184 | } 185 | 186 | void update(int pos, int val) 187 | { 188 | pos--; 189 | QUpd(1,0,N-1,pos,val); 190 | } 191 | 192 | 193 | void display_tree() 194 | { 195 | for(int i=0;i<=10;i++) cout<query_min(1,4); 219 | */ 220 | } 221 | -------------------------------------------------------------------------------- /Segment Tree/segtree_template.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Template for segment tree with range update (lazy) 3 | * Author: asdoc 4 | * Date: 5nd Jan, 2016 5 | * Template Details: 6 | * 1. Define the node of the segment tree, structure name is seg_node 7 | * 2. Define the create_leaf function for your custom tree 8 | * 3. Define the zero() function, which states how your null seg_node will look like 9 | * 4. Define merge() function, which combines result of two nodes and returns parent node 10 | * 5. Define propogate_lazy() function to transfer lazy variables from index to 11 | * it's children and update the value of lazy variable at index 12 | * 6. Update lazy_update(): Change function parameters if necessary 13 | * 7. Update lazy variable of node at index 14 | * 15 | * Tested on: https://www.hackerearth.com/code-monk-segment-tree-and-lazy-propagation/algorithm/monk-and-otakuland-1/ 16 | */ 17 | 18 | #include 19 | #include 20 | using namespace std; 21 | 22 | struct seg_node { 23 | // TODO 1: Define appropriate variables in this structure 24 | 25 | // default variable 26 | int left; 27 | int right; 28 | 29 | // local variable 30 | int cnt; 31 | 32 | // range update variable 33 | bool swap; 34 | }; 35 | 36 | long long n, m, p[280000]; 37 | seg_node seg[800400]; 38 | 39 | seg_node create_leaf(int index) { 40 | // TODO 2: Code for creating the leaf node of index 41 | // N-indexed index 42 | seg_node to_ret; 43 | to_ret.left=index; 44 | to_ret.right=index; 45 | if(p[index-n]==1) { 46 | to_ret.cnt = 1; 47 | } else { 48 | to_ret.cnt = 0; 49 | } 50 | to_ret.swap = false; 51 | return to_ret; 52 | } 53 | 54 | inline seg_node zero() { 55 | // TODO 3: Write the function for zero value of seg_node 56 | seg_node to_ret; 57 | to_ret.cnt = 0; 58 | to_ret.swap = false; 59 | return to_ret; 60 | } 61 | 62 | inline seg_node merge(seg_node a, seg_node b) { 63 | // TODO 4: Write the merge function for merging two nodes into a parent node 64 | // Assumption: b.left = a.right + 1 65 | seg_node to_ret; 66 | to_ret.left = a.left; 67 | to_ret.right = b.right; 68 | 69 | to_ret.cnt = a.cnt + b.cnt; 70 | to_ret.swap = false; 71 | 72 | return to_ret; 73 | } 74 | 75 | inline void propogate_lazy(int index) { 76 | // TODO 5: Write a function to transfer lazy variables from index to 77 | // it's children and update the value of lazy variable at index 78 | if(index r && cr > r)) { 93 | // out of range 94 | } else if(l<=cl && r>=cr){ 95 | // completely in range 96 | 97 | // TODO 7: Update the lazy variable of node at index 98 | seg[index].swap^=true; 99 | // END 100 | 101 | propogate_lazy(index); 102 | } else { 103 | int mid = (cl+cr)/2; 104 | if(r<=mid) { 105 | // not in range of right child 106 | lazy_update(2*index, l, r); 107 | propogate_lazy(2*index+1); 108 | } else if(l>=(mid+1)) { 109 | // not in range of left child 110 | propogate_lazy(2*index); 111 | lazy_update(2*index+1, l, r); 112 | } else { 113 | // in partial range of both children 114 | lazy_update(2*index, l, r); 115 | lazy_update(2*index+1, l, r); 116 | } 117 | seg[index] = merge(seg[2*index], seg[2*index+1]); 118 | } 119 | } 120 | 121 | seg_node query(int index, int l, int r) { 122 | // This function need not be changed 123 | propogate_lazy(index); 124 | int cl = seg[index].left, cr = seg[index].right; 125 | seg_node to_ret; 126 | if(index>=n) { 127 | if(l<=index && r>=index) { 128 | // leaf node, in range 129 | to_ret = seg[index]; 130 | } else { 131 | // leaf node, not in range 132 | to_ret = zero(); 133 | } 134 | } else { 135 | if((cl < l && cr < l) || (cl > r && cr > r)) { 136 | // out of range 137 | to_ret = zero(); 138 | } else if(l<=cl && r>=cr){ 139 | // completely in range 140 | to_ret = seg[index]; 141 | } else { 142 | int mid = (cl+cr)/2; 143 | if(r<=mid) { 144 | // not in range of right child 145 | to_ret = query(2*index, l, r); 146 | } else if(l>=(mid+1)) { 147 | // not in range of left child 148 | to_ret = query(2*index+1, l, r); 149 | } else { 150 | // in partial range of both children 151 | seg_node a = query(2*index, l, r); 152 | seg_node b = query(2*index+1, l, r); 153 | to_ret = merge(a, b); 154 | } 155 | } 156 | } 157 | return to_ret; 158 | } 159 | 160 | void build() { 161 | // This function need not be changed 162 | for(int i=n;i<2*n;i++) { 163 | seg[i].left = i; 164 | seg[i].right = i; 165 | seg[i].swap = false; 166 | if(p[i-n]==1) { 167 | seg[i].cnt = 1; 168 | } else { 169 | seg[i].cnt = 0; 170 | } 171 | // seg[i] = create_leaf(i); 172 | } 173 | for(int i=n-1;i>=1;i--) { 174 | seg[i].cnt = seg[2*i].cnt + seg[2*i+1].cnt; 175 | seg[i].left = seg[2*i].left; 176 | seg[i].right = seg[2*i+1].right; 177 | seg[i].swap = false; 178 | //seg[i] = merge(seg[2*i], seg[2*i+1]); 179 | } 180 | } 181 | 182 | void solve() { 183 | memset(p, 0, sizeof p); 184 | cin >> n >> m; 185 | n-=1; 186 | string s; 187 | cin >> s; 188 | for(int i=0;i') { 190 | p[i]=1; 191 | } else { 192 | p[i]=0; 193 | } 194 | } 195 | int nn = 1; 196 | while(nn> op >> x >> y; 204 | if(op==1) { 205 | lazy_update(1, n-1+x, n-1+y-1); 206 | } else { 207 | if(x>y) { 208 | int val = query(1, n-1+y, n-1+x-1).cnt; 209 | cout << val << "\n" ; 210 | } else { 211 | int val = query(1, n-1+x, n-1+y-1).cnt; 212 | cout << y - x - val << "\n" ; 213 | } 214 | } 215 | } 216 | } 217 | 218 | int main() { 219 | ios_base::sync_with_stdio(false); 220 | cin.tie(0); 221 | int t=1; 222 | while(t--) { 223 | solve(); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /Sieve of Eratosthenes/sieve.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int isPrime[10000]; 5 | 6 | void sieveOptimized(int N) { 7 | for (int i = 2; i <= N; i++) 8 | isPrime[i] = 1; 9 | for (int i = 2; i * i <= N; i++) { 10 | if (isPrime[i]) { 11 | // For further optimization, You can do instead of j += i, j += (2 * i). 12 | // Proof is left to reader :) 13 | for (int j = i * i; j <= N; j += i) 14 | isPrime[j] = 0; 15 | } 16 | } 17 | } 18 | int main() 19 | { 20 | sieveOptimized(100); 21 | for(int j=0;j<100;j++) 22 | if(isPrime[j]) 23 | cout < 8 | 9 | using namespace std; 10 | 11 | template > 12 | class SparseTable { 13 | public: 14 | int n; 15 | vector> mat; 16 | F func; 17 | 18 | SparseTable(const vector& a, const F& f) : func(f) { 19 | n = static_cast(a.size()); 20 | int max_log = 32 - __builtin_clz(n); 21 | mat.resize(max_log); 22 | mat[0] = a; 23 | for (int j = 1; j < max_log; j++) { 24 | mat[j].resize(n - (1 << j) + 1); 25 | for (int i = 0; i <= n - (1 << j); i++) { 26 | mat[j][i] = func(mat[j - 1][i], mat[j - 1][i + (1 << (j - 1))]); 27 | } 28 | } 29 | } 30 | 31 | T get(int from, int to) const { 32 | assert(0 <= from && from <= to && to <= n - 1); 33 | int lg = 32 - __builtin_clz(to - from + 1) - 1; 34 | return func(mat[lg][from], mat[lg][to - (1 << lg) + 1]); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /Suffix Array Construction/nlog2n.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #define MAXN 1001 6 | using namespace std; 7 | 8 | struct Triple { 9 | int index; 10 | int fh, sh; 11 | }; 12 | 13 | int cmp(Triple a, Triple b) { 14 | if(a.fh==b.fh) return a.sh rad[MAXN]; 19 | 20 | int main() { 21 | string s; 22 | cin>>s; 23 | int len = s.length(); 24 | int rank[len][20]; 25 | Triple a[len]; 26 | for(int i=0;i 2 | #include 3 | #include 4 | #include 5 | #define MAXN 1001 6 | using namespace std; 7 | 8 | struct Triple { 9 | int index; 10 | int fh, sh; 11 | }; 12 | 13 | int cmp(Triple a, Triple b) { 14 | if(a.fh==b.fh) return a.sh rad[MAXN]; 19 | 20 | int main() { 21 | string s; 22 | cin>>s; 23 | int len = s.length(); 24 | int rank[len][20]; 25 | Triple a[len]; 26 | for(int i=0;i 2 | using namespace std; 3 | 4 | /* 5 | * Credits: https://github.com/chemthan/chemthan 6 | * Complexity: O(N) 7 | * Problem: 8 | * 1. http://codeforces.com/problemset/problem/128/B 9 | */ 10 | const int MAXN = 1e5 + 5; 11 | const int MAXC = 26; 12 | struct state { 13 | int len, link, fpos; 14 | int nxt[MAXC]; 15 | }; 16 | struct SuffixAutomaton { 17 | state st[MAXN << 1]; 18 | int nsz, last; 19 | int cnt[MAXN << 1]; 20 | long long nchild[MAXN << 1]; 21 | void init() { 22 | st[0].len = 0; 23 | st[0].link = -1; 24 | st[0].fpos = 0; 25 | memset(st[0].nxt, -1, sizeof(st[0].nxt)); 26 | nsz = 1; last = 0; 27 | cnt[0] = nchild[0] = 0; 28 | } 29 | void extend(char c) { 30 | int cur = nsz++; 31 | st[cur].len = st[last].len + 1; 32 | st[cur].fpos = st[cur].len - 1; 33 | memset(st[cur].nxt, -1, sizeof(st[cur].nxt)); 34 | cnt[cur] = 1; nchild[cur] = 0; 35 | int p; 36 | for (p = last; ~p && !~st[p].nxt[c]; p = st[p].link) st[p].nxt[c] = cur; 37 | if (!~p) st[cur].link = 0; 38 | else { 39 | int q = st[p].nxt[c]; 40 | if (st[p].len + 1 == st[q].len) st[cur].link = q; 41 | else { 42 | int clone = nsz++; 43 | st[clone].len = st[p].len + 1; 44 | memcpy(st[clone].nxt, st[q].nxt, sizeof(st[q].nxt)); 45 | st[clone].link = st[q].link; 46 | st[clone].fpos = st[q].fpos; 47 | cnt[clone] = 0; nchild[clone] = 0; 48 | for (; ~p && st[p].nxt[c] == q; p = st[p].link) st[p].nxt[c] = clone; 49 | st[q].link = st[cur].link = clone; 50 | } 51 | } 52 | last = cur; 53 | } 54 | char cur[MAXN]; 55 | void trace(int u, int len = 0) { 56 | for (int i = 0; i < MAXC; i++) { 57 | if (~st[u].nxt[i]) { 58 | cur[len] = 'a' + i; 59 | cur[len + 1] = 0; 60 | cout << cur << "\n"; 61 | trace(st[u].nxt[i], len + 1); 62 | cur[len] = 0; 63 | } 64 | } 65 | } 66 | long long ndsubstr(int u) { 67 | if (nchild[u]) return nchild[u]; 68 | nchild[u] = 1; 69 | for (int i = 0; i < MAXC; i++) { 70 | if (~st[u].nxt[i]) { 71 | nchild[u] += ndsubstr(st[u].nxt[i]); 72 | } 73 | } 74 | return nchild[u]; 75 | } 76 | string kth(int u, int k) { 77 | if (!k) return ""; 78 | int tot = 0; 79 | for (int i = 0; i < MAXC; i++) { 80 | if (~st[u].nxt[i]) { 81 | int v = st[u].nxt[i]; 82 | if (tot + nchild[v] >= k) { 83 | return char('a' + i) + kth(v, k - tot - 1); 84 | } 85 | tot += nchild[v]; 86 | } 87 | } 88 | return ""; 89 | } 90 | int minshift(int u, int k) { 91 | if (!k) return st[u].fpos; 92 | for (int i = 0; i < MAXC; i++) { 93 | if (~st[u].nxt[i]) { 94 | return minshift(st[u].nxt[i], k - 1); 95 | } 96 | } 97 | } 98 | void updatesize() { 99 | vector v, vis(nsz, 0); 100 | queue q; 101 | q.push(0); vis[0] = 1; 102 | while (q.size()) { 103 | int u = q.front(); q.pop(); 104 | v.push_back(u); 105 | for (int i = 0; i < MAXC; i++) { 106 | if (~st[u].nxt[i] && !vis[st[u].nxt[i]]) { 107 | q.push(st[u].nxt[i]); 108 | vis[st[u].nxt[i]] = 1; 109 | } 110 | } 111 | } 112 | for (int i = v.size() - 1; i > 0; i--) { 113 | int u = v[i]; 114 | cnt[st[u].link] += cnt[u]; 115 | } 116 | } 117 | int repstr(string str) { 118 | int idx = 0, cur = 0; 119 | while (cur < str.size()) { 120 | idx = st[idx].nxt[str[cur] - 'a']; 121 | if (!~idx) return 0; 122 | cur++; 123 | } 124 | return cnt[idx]; 125 | } 126 | int firstpostn(string str) { 127 | int cur = 0, vtx = 0; 128 | while (cur < str.size()) { 129 | vtx = st[vtx].nxt[str[cur] - 'a']; 130 | if (!~vtx) return -1; 131 | cur++; 132 | } 133 | return st[vtx].fpos - str.size() + 1; 134 | } 135 | } sa; 136 | 137 | string lcs(string s, string t) { 138 | sa.init(); 139 | for (int i = 0; i < s.size(); i++) { 140 | sa.extend(s[i] - 'a'); 141 | } 142 | int v = 0, l = 0, best = 0, bestpos = 0; 143 | for (int i = 0; i < t.size(); i++) { 144 | while (v && !~sa.st[v].nxt[t[i] - 'a']) { 145 | v = sa.st[v].link; 146 | l = sa.st[v].len; 147 | } 148 | if (~sa.st[v].nxt[t[i] - 'a']) { 149 | v = sa.st[v].nxt[t[i] - 'a']; 150 | l++; 151 | } 152 | if (best < l) { 153 | best = l; 154 | bestpos = i; 155 | } 156 | } 157 | return t.substr(bestpos - best + 1, best); 158 | } 159 | 160 | int main() { 161 | string s = "bcabc"; 162 | sa.init(); 163 | for (int i = 0; i < s.size(); i++) { 164 | sa.extend(s[i] - 'a'); 165 | } 166 | sa.trace(0); cout << "\n"; 167 | cout << sa.ndsubstr(0) << "\n"; //Total distinct substring, include empty one 168 | cout << sa.kth(0, 3) << "\n"; //kth smallest substring 169 | sa.updatesize(); 170 | cout << sa.repstr("e") << "\n"; //The number of occurrences 171 | s += s; 172 | sa.init(); 173 | for (int i = 0; i < s.size(); i++) { 174 | sa.extend(s[i] - 'a'); 175 | } 176 | cout << sa.minshift(0, s.size() >> 1) - (s.size() >> 1) + 1 << "\n"; 177 | cout << sa.firstpostn("ab") << "\n"; 178 | cout << lcs("abcdef", "gcdeft") << "\n"; 179 | return 0; 180 | } 181 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | A list of data strucctures and algorithms yet to be added: 4 | 5 | - Maximum Bipartite Matching 6 | - Bridges in a Graph 7 | - KMP String Matching 8 | - Suffix Tree 9 | - FFT, NTT, FFT with large modulo 10 | - LCA 11 | - Strongly Connected Components 12 | - Aho-Corasick 13 | - Matrix Operations (in Python) 14 | - Rolling Hash (Rabin-Karp) 15 | - Gauss Elimination 16 | - BIT (PointUpdate+RangeQuery, RangeUpdate+RangeQuery) 17 | -------------------------------------------------------------------------------- /Trie/iterative_trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define end _end 6 | #define next _nxt 7 | 8 | const int MaxN = 500500; 9 | int sz = 0; 10 | 11 | int next[27][MaxN]; 12 | int end[MaxN]; 13 | bool created[MaxN]; 14 | 15 | void insert (string &s) { 16 | int v = 0; 17 | 18 | for (int i = 0; i < s.size(); ++i) { 19 | int c = s[i] - 'a'; 20 | if (!created[next[c][v]]) { 21 | next[c][v] = ++sz; 22 | created[sz] = true; 23 | } 24 | v = next[c][v]; 25 | } 26 | ++end[v]; 27 | } 28 | 29 | bool search (string tmp) { 30 | int v = 0; 31 | 32 | for (int i = 0; i < tmp.size(); ++i) { 33 | int c = tmp[i] - 'a'; 34 | if (!created[next[c][v]]) 35 | return false; 36 | v = next[c][v]; 37 | } 38 | return end[v] > 0; 39 | } 40 | 41 | int main () { 42 | string keys[] = {"hi", "hello", "you", "ekta", "me"}; 43 | string output[] = {"NO", "YES"}; 44 | 45 | for (int i = 0; i < 5; ++i) 46 | insert (keys[i]); 47 | 48 | cout << output[search ("my")] << endl; 49 | cout << output[search ("me")] << endl; 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /Wavelet Tree/wavelet_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define gc getchar_unlocked 4 | #define fo(i,n) for(i=0;in;k 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | std::mt19937 rng((int) std::chrono::steady_clock::now().time_since_epoch().count()); 9 | 10 | template 11 | class XorGauss { 12 | public: 13 | XorGauss() { 14 | for(int i = 0; i < N; i++) { a[i] = 0; } 15 | } 16 | T reduce(T x) { 17 | for(int i = N-1; i >= 0; i--) { 18 | x = std::min(x, x ^ a[i]); 19 | } 20 | return x; 21 | } 22 | 23 | T augment(T x) { return ~reduce(~x); } 24 | 25 | bool add(T x) { 26 | for(int i = N-1; i >= 0; i--) { 27 | if((x & (((T)1) << i)) == 0) { continue; } 28 | if(a[i]) { 29 | x ^= a[i]; 30 | } else { 31 | a[i] = x; 32 | for(int j = i-1; j >= 0; j--) { 33 | a[i] = std::min(a[i], a[i] ^ a[j]); 34 | } 35 | for(int j = i+1; j < N; j++) { 36 | a[j] = std::min(a[j], a[j] ^ a[i]); 37 | } 38 | return true; 39 | } 40 | } 41 | return false; 42 | } 43 | 44 | std::vector getWeird() { 45 | //for(int i = 0; i < N; i++) { 46 | // if(a[i]) std::cout << a[i] << ' '; 47 | //}std::cout << '\n'; 48 | std::vector good; 49 | for(int i = 0; i < N; i++) { 50 | if(a[i]) continue; 51 | bool ha = true; 52 | for(int j = 0; j < N; j++) { 53 | ha = ha || (a[j] & (1LL << j)) == 0; 54 | } 55 | if(ha) good.push_back(i); 56 | } 57 | std::vector ans; 58 | for(int i = 0; i < N; i++) { 59 | if(!a[i]) continue; 60 | ans.push_back(0); 61 | for(int j = 0; j < (int) good.size(); j++) { 62 | if(a[i] & (1LL << good[j])) { 63 | ans.back() |= 1LL << j; 64 | } 65 | } 66 | //std::cout << ans.back() << ' '; 67 | }//std::cout << '\n'; 68 | return ans; 69 | } 70 | private: 71 | T a[N]; 72 | }; 73 | 74 | typedef XorGauss<60, long long> Gauss; 75 | -------------------------------------------------------------------------------- /binary_search_utils/bs_utils.py: -------------------------------------------------------------------------------- 1 | from bisect import bisect_left, bisect_right 2 | 3 | def index(a, x): 4 | 'Locate the leftmost value exactly equal to x' 5 | i = bisect_left(a, x) 6 | if i != len(a) and a[i] == x: 7 | return i 8 | raise ValueError 9 | 10 | def find_lt(a, x): 11 | 'Find rightmost value less than x' 12 | i = bisect_left(a, x) 13 | if i: 14 | return a[i-1] 15 | raise ValueError 16 | 17 | def find_le(a, x): 18 | 'Find rightmost value less than or equal to x' 19 | i = bisect_right(a, x) 20 | if i: 21 | return a[i-1] 22 | raise ValueError 23 | 24 | def find_gt(a, x): 25 | 'Find leftmost value greater than x' 26 | i = bisect_right(a, x) 27 | if i != len(a): 28 | return a[i] 29 | raise ValueError 30 | 31 | def find_ge(a, x): 32 | 'Find leftmost item greater than or equal to x' 33 | i = bisect_left(a, x) 34 | if i != len(a): 35 | return a[i] 36 | raise ValueError 37 | -------------------------------------------------------------------------------- /fast_mod_mul_barrett_reduction/barrett_reduction.cpp: -------------------------------------------------------------------------------- 1 | // Fast modular multiplication by barrett reduction 2 | // Reference: https://en.wikipedia.org/wiki/Barrett_reduction 3 | // NOTE: reconsider after Ice Lake 4 | struct barrett { 5 | unsigned int _m; 6 | unsigned long long im; 7 | 8 | // @param m `1 <= m < 2^31` 9 | barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {} 10 | 11 | // @return m 12 | unsigned int umod() const { return _m; } 13 | 14 | // @param a `0 <= a < m` 15 | // @param b `0 <= b < m` 16 | // @return `a * b % m` 17 | unsigned int mul(unsigned int a, unsigned int b) const { 18 | // [1] m = 1 19 | // a = b = im = 0, so okay 20 | 21 | // [2] m >= 2 22 | // im = ceil(2^64 / m) 23 | // -> im * m = 2^64 + r (0 <= r < m) 24 | // let z = a*b = c*m + d (0 <= c, d < m) 25 | // a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im 26 | // c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2 27 | // ((ab * im) >> 64) == c or c + 1 28 | unsigned long long z = a; 29 | z *= b; 30 | #ifdef _MSC_VER 31 | unsigned long long x; 32 | _umul128(z, im, &x); 33 | #else 34 | unsigned long long x = 35 | (unsigned long long)(((unsigned __int128)(z)*im) >> 64); 36 | #endif 37 | unsigned int v = (unsigned int)(z - x * _m); 38 | if (_m <= v) v += _m; 39 | return v; 40 | } 41 | }; 42 | --------------------------------------------------------------------------------