├── 2D Segtree.cpp ├── 3D hull.cpp ├── Aho Corsik.cpp ├── BFS.cpp ├── BFS_Graph_template.cpp ├── Chinese Remainder Theorem.cpp ├── DP_Opti : Divide & Conquer.cpp ├── DSU.cpp ├── Delauney.cpp ├── Dynamic Convex Hull.cpp ├── FFT.cpp ├── Graph Power Library.cpp ├── GraphX.cpp ├── HLD.cpp ├── KD Tree.cpp ├── Matrix Determinant.cpp ├── Matrix Expo.cpp ├── Miller Rabin + mod_Mull.cpp ├── Min Vertex Cover.cpp ├── MinCostMaxFlow.cpp ├── NTT.cpp ├── Neeraj_FFT.cpp ├── Network Flows.cpp ├── Policy BST.cpp ├── Pollard Rho- Factors.cpp ├── README.md ├── RabinKarp String Hash.cpp ├── Sieve with logN factor queries.cpp ├── SimpleGraphTemplate.cpp ├── SimpleGraphTemplate.java ├── SimpleGraphTemplate.py ├── Simplex.cpp ├── SplitString+stoi.cpp ├── articulation points.cpp ├── bit tricks.cpp ├── circle_tangent.cpp ├── circum circle.cpp ├── dates.cpp ├── dfsmatching.cpp ├── fraction class ├── geometry.cpp ├── manacher.cpp ├── nCr with mod precompute.cpp ├── phi.cpp ├── point in poly log N.cpp ├── random_distributions.cpp ├── spherical distance.cpp ├── ternary search.cpp ├── treap.cpp └── unordered_map for pair as key /2D Segtree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define pb push_back 4 | #define ll long long int 5 | 6 | typedef struct node { 7 | int l,r,x,y; 8 | ll val; 9 | struct node *ul,*ur,*lll,*lr; 10 | } node; 11 | 12 | int ar[1030][1030]; 13 | ll kam,zyada; 14 | 15 | node* build(int l,int r,int x,int y) { 16 | //cout<r || x>y) return NULL; 18 | node* ne = (node*)malloc(sizeof(node)); 19 | ne->l = l; 20 | ne->r = r; 21 | ne->y = y; 22 | ne->x = x; 23 | if(l==r&&x==y) { 24 | ne->val = ar[l][x]; 25 | return ne; 26 | } 27 | ne->ul = build(l,(l+r)/2,x,(x+y)/2); 28 | if(ne->ul) 29 | ne->val += ne->ul->val;//.pb(ne->ul->ve[i]); 30 | ne->ur = build(l,(l+r)/2,(x+y)/2+1,y); 31 | if(ne->ur) 32 | ne->val += ne->ur->val;//.pb(ne->ur->ve[i]); 33 | ne->lll = build((l+r)/2+1,r,x,(x+y)/2); 34 | if(ne->lll) 35 | ne->val += ne->lll->val;//.pb(ne->ur->ve[i]); 36 | ne->lr = build((l+r)/2+1,r,(x+y)/2+1,y); 37 | if(ne->lr) 38 | ne->val += ne->lr->val;//.pb(ne->ur->ve[i]); 39 | return ne; 40 | } 41 | 42 | void query(node *t,int l1,int r1,int x1,int y1,int l2,int r2,int x2,int y2) { 43 | // cout<r1||x1>y1) return; 45 | if(l1>=l2 && r1<=r2 && x1>=x2 && y1<=y2) { 46 | kam += t->val; 47 | return; 48 | } 49 | if(l2<=(l1+r1)/2 && x2<=(x1+y1)/2) 50 | query(t->ul,l1,(l1+r1)/2,x1,(x1+y1)/2,l2,r2,x2,y2); 51 | if(l2<=(l1+r1)/2 && y2>(x1+y1)/2) 52 | query(t->ur,l1,(l1+r1)/2,(x1+y1)/2+1,y1,l2,r2,x2,y2); 53 | if(r2>(l1+r1)/2 && x2<=(x1+y1)/2) 54 | query(t->lll,(l1+r1)/2+1,r1,x1,(x1+y1)/2,l2,r2,x2,y2); 55 | if(r2>(l1+r1)/2 && y2>(x1+y1)/2) 56 | query(t->lr,(l1+r1)/2+1,r1,(x1+y1)/2+1,y1,l2,r2,x2,y2); 57 | } 58 | 59 | void update(node *t,int l1,int r1,int x1,int y1,int l2,int x2,int val1,int val2) { 60 | //cout<r1||x1>y1) return; 62 | t->val += val2; 63 | t->val -= val1; 64 | if(l1==r1&&x1==y1) return; 65 | if(l2<=(l1+r1)/2 && x2<=(x1+y1)/2) 66 | update(t->ul,l1,(l1+r1)/2,x1,(x1+y1)/2,l2,x2,val1,val2); 67 | if(l2<=(l1+r1)/2 && x2>(x1+y1)/2) 68 | update(t->ur,l1,(l1+r1)/2,(x1+y1)/2+1,y1,l2,x2,val1,val2); 69 | if(l2>(l1+r1)/2 && x2<=(x1+y1)/2) 70 | update(t->lll,(l1+r1)/2+1,r1,x1,(x1+y1)/2,l2,x2,val1,val2); 71 | if(l2>(l1+r1)/2 && x2>(x1+y1)/2) 72 | update(t->lr,(l1+r1)/2+1,r1,(x1+y1)/2+1,y1,l2,x2,val1,val2); 73 | } 74 | 75 | int main() { 76 | ios::sync_with_stdio(false);cin.tie(0); 77 | int t; 78 | cin>>t; 79 | while(t--) { 80 | node* head = (node*)malloc(sizeof(node)); 81 | int i,j,k,l,n,x,q,y,r; 82 | string s; 83 | cin>>n; 84 | for(i=0;i>s; 89 | while(s[0]=='S') { 90 | cin>>l>>r>>x; 91 | kam=0; 92 | if(s[1]=='U') { 93 | cin>>y; 94 | query(head,0,n-1,0,n-1,l,x,r,y); 95 | cout<>s; 102 | } 103 | } 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /3D hull.cpp: -------------------------------------------------------------------------------- 1 | template struct Point3D { 2 | typedef Point3D P; 3 | typedef const P& R; 4 | T x, y, z; 5 | explicit Point3D(T x=0, T y=0, T z=0) : x(x), y(y), z(z) {} 6 | bool operator<(R p) const { 7 | return tie(x, y, z) < tie(p.x, p.y, p.z); } 8 | bool operator==(R p) const { 9 | return tie(x, y, z) == tie(p.x, p.y, p.z); } 10 | P operator+(R p) const { return P(x+p.x, y+p.y, z+p.z); } 11 | P operator-(R p) const { return P(x-p.x, y-p.y, z-p.z); } 12 | P operator*(T d) const { return P(x*d, y*d, z*d); } 13 | P operator/(T d) const { return P(x/d, y/d, z/d); } 14 | T dot(R p) const { return x*p.x + y*p.y + z*p.z; } 15 | P cross(R p) const { 16 | return P(y*p.z - z*p.y, z*p.x - x*p.z, x*p.y - y*p.x); 17 | } 18 | T dist2() const { return x*x + y*y + z*z; } 19 | double dist() const { return sqrt((double)dist2()); } 20 | //Azimuthal angle (longitude) to x-axis in interval [-pi, pi] 21 | double phi() const { return atan2(y, x); } 22 | //Zenith angle (latitude) to the z-axis in interval [0, pi] 23 | double theta() const { return atan2(sqrt(x*x+y*y),z); } 24 | P unit() const { return *this/(T)dist(); } //makes dist()=1 25 | //returns unit vector normal to *this and p 26 | P normal(P p) const { return cross(p).unit(); } 27 | //returns point rotated 'angle' radians ccw around axis 28 | P rotate(double angle, P axis) const { 29 | double s = sin(angle), c = cos(angle); P u = axis.unit(); 30 | return u*dot(u)*(1-c) + (*this)*c - cross(u)*s; 31 | } 32 | }; 33 | 34 | typedef Point3D P3; 35 | 36 | struct PR { 37 | void ins(int x) { (a == -1 ? a : b) = x; } 38 | void rem(int x) { (a == x ? a : b) = -1; } 39 | int cnt() { return (a != -1) + (b != -1); } 40 | int a, b; 41 | }; 42 | 43 | struct F { P3 q; int a, b, c; }; 44 | 45 | vector hull3d(const vector& A) { 46 | assert(sz(A) >= 4); 47 | vector> E(sz(A), vector(sz(A), {-1, -1})); 48 | #define E(x,y) E[f.x][f.y] 49 | vector FS; 50 | auto mf = [&](int i, int j, int k, int l) { 51 | P3 q = (A[j] - A[i]).cross((A[k] - A[i])); 52 | if (q.dot(A[l]) > q.dot(A[i])) 53 | q = q * -1; 54 | F f{q, i, j, k}; 55 | E(a,b).ins(k); E(a,c).ins(j); E(b,c).ins(i); 56 | FS.push_back(f); 57 | }; 58 | rep(i,0,4) rep(j,i+1,4) rep(k,j+1,4) 59 | mf(i, j, k, 6 - i - j - k); 60 | 61 | rep(i,4,sz(A)) { 62 | rep(j,0,sz(FS)) { 63 | F f = FS[j]; 64 | if(f.q.dot(A[i]) > f.q.dot(A[f.a])) { 65 | E(a,b).rem(f.c); 66 | E(a,c).rem(f.b); 67 | E(b,c).rem(f.a); 68 | swap(FS[j--], FS.back()); 69 | FS.pop_back(); 70 | } 71 | } 72 | int nw = sz(FS); 73 | rep(j,0,nw) { 74 | F f = FS[j]; 75 | #define C(a, b, c) if (E(a,b).cnt() != 2) mf(f.a, f.b, i, f.c); 76 | C(a, b, c); C(a, c, b); C(b, c, a); 77 | } 78 | } 79 | trav(it, FS) if ((A[it.b] - A[it.a]).cross( 80 | A[it.c] - A[it.a]).dot(it.q) <= 0) swap(it.c, it.b); 81 | return FS; 82 | }; 83 | -------------------------------------------------------------------------------- /Aho Corsik.cpp: -------------------------------------------------------------------------------- 1 | #define inc(i,a,b) for(int i=a;i<=b;++i) 2 | #define pb push_back 3 | 4 | const int maxWords = 506, maxLyrics = 106, maxWordLength = 5006, maxLyricLength = 50006; 5 | 6 | struct node { 7 | int occ, failIndegree; 8 | map edge; 9 | node* fail; 10 | 11 | node():occ(0),failIndegree(0),fail(NULL) {} 12 | }root; 13 | 14 | int numWords, numLyrics; 15 | node* id[maxWords]; 16 | 17 | void preComputation(); 18 | void searchTarget(); 19 | void getOccurances(); 20 | void buildTrie(); 21 | void buildAutomaton(); 22 | 23 | int main() { 24 | scanf("%d",&numWords); 25 | preComputation(); 26 | 27 | scanf("%d",&numLyrics); 28 | inc(i,1,numLyrics) { 29 | searchTarget(); 30 | } 31 | getOccurances(); 32 | 33 | inc(i,0,numWords-1) { 34 | printf("%d\n",id[i]->occ); 35 | } 36 | } 37 | 38 | void buildTrie() { 39 | char word[maxWordLength], c; 40 | 41 | inc(i,0,numWords-1) { 42 | cin >> word; 43 | id[i] = &root; 44 | 45 | for(int j=0;word[j];++j) { 46 | c = word[j]; 47 | assert(isalnum(c) || c=='-'); 48 | if(!id[i]->edge.count(c)) { 49 | id[i]->edge[c] = new node; 50 | } 51 | id[i] = id[i]->edge[c]; 52 | } 53 | } 54 | } 55 | void buildAutomaton() { 56 | queue q; 57 | 58 | vector alpha; 59 | inc(i,'a','z') alpha.pb(i); 60 | inc(i,'A','Z') alpha.pb(i); 61 | inc(i,'0','9') alpha.pb(i); 62 | alpha.pb('-'); 63 | 64 | // Gives root more failIndegree so that it isn't added to queue in getOccurances() 65 | root.failIndegree = 1; 66 | 67 | inc(i,0,alpha.size()-1) { 68 | if(!root.edge.count(alpha[i])) { 69 | root.edge[alpha[i]] = &root; 70 | } 71 | else { 72 | root.edge[alpha[i]]->fail = &root; 73 | (root.failIndegree)++; 74 | q.push(root.edge[alpha[i]]); 75 | } 76 | } 77 | 78 | while(!q.empty()) { 79 | node* p = q.front(); 80 | q.pop(); 81 | 82 | map::iterator it = p->edge.begin(); 83 | for(;it!=p->edge.end();++it) { 84 | node *u = it->second; 85 | char c = it->first; 86 | 87 | node *v = p->fail; 88 | while(!v->edge.count(c)) { 89 | 90 | v = v->fail; 91 | } 92 | u->fail = v->edge[c]; 93 | (v->edge[c]->failIndegree)++; 94 | 95 | q.push(u); 96 | } 97 | } 98 | } 99 | void preComputation() { 100 | buildTrie(); 101 | buildAutomaton(); 102 | } 103 | void searchTarget() { 104 | char lyric[maxLyricLength]; 105 | scanf(" %s",lyric); 106 | 107 | node* curr = &root; 108 | char c; 109 | for(int i=0;lyric[i];++i) { 110 | c = lyric[i]; 111 | while(!curr->edge.count(c)) { 112 | assert(curr->fail != NULL); 113 | curr = curr->fail; 114 | } 115 | curr = curr->edge[c]; 116 | (curr->occ)++; 117 | } 118 | } 119 | void getOccurances() { 120 | queue q; 121 | 122 | queue bfs; 123 | bfs.push(&root); 124 | while(!bfs.empty()) { 125 | node* u = bfs.front(); 126 | bfs.pop(); 127 | 128 | if(!u->failIndegree) q.push(u); 129 | 130 | map::iterator it = u->edge.begin(); 131 | for(;it!=u->edge.end();++it) { 132 | node* v = it->second; 133 | if(v!=(&root)) bfs.push(v); 134 | } 135 | } 136 | 137 | while(!q.empty()) { 138 | node* u = q.front(); 139 | q.pop(); 140 | 141 | assert(u->fail != NULL); 142 | node* v = u->fail; 143 | 144 | (v->failIndegree)--; 145 | if(!v->failIndegree) { 146 | assert(v!=(&root)); 147 | q.push(v); 148 | } 149 | 150 | v->occ += u->occ; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /BFS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | //COPY THE BLACKBOX, there is no need to change anything in it. 9 | //Check the main function at bottom for USAGE 10 | 11 | //****************BLACKBOX START***************** 12 | //START COPYING FROM HERE 13 | class Graph { 14 | public: 15 | 16 | Graph(int num_nodes) 17 | : adj_list(num_nodes), dist(num_nodes, -1) {} 18 | 19 | void add_edge(int start, int end); 20 | vector> adj_list; 21 | vector dist; 22 | }; 23 | 24 | void Graph::add_edge(int start, int end) { 25 | adj_list[start].push_back(end); 26 | } 27 | 28 | vector BFS(Graph& g, int source) { 29 | vector visited(g.adj_list.size(), false); 30 | queue q; 31 | q.push(source); 32 | 33 | visited[source] = true; 34 | g.dist[source] = 0; 35 | 36 | while(!q.empty()) { 37 | int cur_node = q.front(); 38 | vector cur_node_adj = g.adj_list[cur_node]; 39 | 40 | for (unsigned int i = 0; i < cur_node_adj.size(); ++i) { 41 | int adj_node = cur_node_adj[i]; 42 | if (visited[adj_node] == false) { 43 | visited[adj_node] = true; 44 | g.dist[adj_node] = g.dist[cur_node] + 1; 45 | q.push(adj_node); 46 | } 47 | } 48 | q.pop(); 49 | } 50 | 51 | return g.dist; 52 | } 53 | //END COPYING HERE 54 | //********************BLACKBOX END****************** 55 | 56 | 57 | int main() { 58 | // initaitise a graph with 4 nodes, nodes are 0-indexed 59 | Graph g(4); 60 | 61 | //DIRECTED GRAPH : add edges `Node 0 -> Node 4` and `Node 1 -> Node 3` 62 | g.add_edge(0,4); 63 | g.add_edge(1,3); 64 | 65 | //UNDIRECT GRAPH : add edges between `Node 0 -- Node 4` and `Node 1 -- Node 3` 66 | g.add_edge(0,4); 67 | g.add_edge(4,0); 68 | g.add_edge(1,3); 69 | g.add_edge(3,1); 70 | 71 | //do BFS on the graph g start at `Node 2` 72 | //An array of size "number of nodes" is returned with the minimum distance from `Node 2` to each node, i.e. `shortest path length from Node 2 -> Node 3 = min_dist[3] ` 73 | //If a `Node i` is unreachable from `Node 2`, then `min_dist[i]=-1` 74 | vectormin_dist = BFS(g, 2); 75 | 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /BFS_Graph_template.cpp: -------------------------------------------------------------------------------- 1 | // BFS algorithm in C++ 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | //********************* BLACKBOX STARTS 9 | // Copy this section as it is (Refer main function at bottom for usage, that is all that you need) 10 | class Graph { 11 | int numVertices; 12 | list* adjLists; 13 | bool* visited; 14 | 15 | public: 16 | Graph(int vertices); 17 | void addEdge(int src, int dest); 18 | void BFS(int startVertex); 19 | }; 20 | 21 | // Create a graph with given vertices, 22 | // and maintain an adjacency list 23 | Graph::Graph(int vertices) { 24 | numVertices = vertices; 25 | adjLists = new list[vertices]; 26 | } 27 | 28 | // Add edges to the graph 29 | void Graph::addEdge(int src, int dest) { 30 | adjLists[src].push_back(dest); 31 | } 32 | 33 | // BFS algorithm 34 | void Graph::BFS(int startVertex) { 35 | visited = new bool[numVertices]; 36 | for (int i = 0; i < numVertices; i++) 37 | visited[i] = false; 38 | 39 | list queue; 40 | 41 | visited[startVertex] = true; 42 | queue.push_back(startVertex); 43 | 44 | list::iterator i; 45 | 46 | while (!queue.empty()) { 47 | int currVertex = queue.front(); 48 | cout << "Visited " << currVertex << " "; 49 | queue.pop_front(); 50 | 51 | for (i = adjLists[currVertex].begin(); i != adjLists[currVertex].end(); ++i) { 52 | int adjVertex = *i; 53 | if (!visited[adjVertex]) { 54 | visited[adjVertex] = true; 55 | queue.push_back(adjVertex); 56 | } 57 | } 58 | } 59 | } 60 | //BLACKBOX ENDS 61 | //************************* 62 | 63 | int main() { 64 | Graph g(4); //Create new Graph g with 4 nodes 65 | g.addEdge(0, 1); //Add DIRECTED edges to graph g from 0 to 1. If you have UNDIRECTED graph, simply also add edge(1->0) 66 | g.addEdge(0, 2); 67 | g.addEdge(1, 2); 68 | g.addEdge(2, 0); 69 | g.addEdge(2, 3); 70 | g.addEdge(3, 3); 71 | 72 | g.BFS(2); 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /Chinese Remainder Theorem.cpp: -------------------------------------------------------------------------------- 1 | /* \texttt{chinese(a, m, b, n)} returns a number $x$, such that 2 | * $x\equiv a \pmod m$ and $x\equiv b \pmod n$. For not 3 | * coprime $n, m$, use \texttt{chinese\_common}. Note that all numbers must be less than 4 | * $2^{31}$ if you have Z = unsigned long long. 5 | * Status: Works 6 | * Time: $\log(m + n)$ 7 | */ 8 | ll euclid(ll a, ll b, ll &x, ll &y) { 9 | if (b) { ll d = euclid(b, a % b, y, x); 10 | return y -= a/b * x, d; } 11 | return x = 1, y = 0, a; 12 | } 13 | template Z chinese(Z a, Z m, Z b, Z n) { 14 | Z x, y; euclid(m, n, x, y); 15 | Z ret = a * (y + m) % m * n + b * (x + n) % n * m; 16 | if (ret >= m * n) ret -= m * n; 17 | return ret; 18 | } 19 | 20 | template Z chinese_common(Z a, Z m, Z b, Z n) { 21 | Z d = gcd(m, n); 22 | if (((b -= a) %= n) < 0) b += n; 23 | if (b % d) return -1; // No solution 24 | return d * chinese(Z(0), m/d, b/d, n/d) + a; 25 | } 26 | -------------------------------------------------------------------------------- /DP_Opti : Divide & Conquer.cpp: -------------------------------------------------------------------------------- 1 | /*Given $a[i] = \min_{lo(i) \le k < hi(i)}(f(i, k))$ where the (minimal) optimal $k$ increases with $i$, computes $a[i]$ for $i = L..R-1$. 2 | * Status: tested on http://codeforces.com/contest/321/problem/E 3 | * Time: O((N + (hi-lo)) \log N) */ 4 | struct DP { // Modify at will: 5 | int lo(int ind) { return 0; } 6 | int hi(int ind) { return ind; } 7 | ll f(int ind, int k) { return dp[ind][k]; } 8 | void store(int ind, int k, ll v) { res[ind] = pii(k, v); } 9 | 10 | void rec(int L, int R, int LO, int HI) { 11 | if (L >= R) return; 12 | int mid = (L + R) >> 1; 13 | pair best(LLONG_MAX, LO); 14 | rep(k, max(LO,lo(mid)), min(HI,hi(mid))) 15 | best = min(best, make_pair(f(mid, k), k)); 16 | store(mid, best.second, best.first); 17 | rec(L, mid, LO, best.second+1); 18 | rec(mid+1, R, best.second, HI); 19 | } 20 | void solve(int L, int R) { rec(L, R, INT_MIN, INT_MAX); } 21 | }; 22 | -------------------------------------------------------------------------------- /DSU.cpp: -------------------------------------------------------------------------------- 1 | struct DSU { 2 | //int gans=0; 3 | int root(int v){return par[v] < 0 ? v : (par[v] = root(par[v]));} 4 | void merge(int x,int y){ 5 | if((x = root(x)) == (y = root(y))) return ; 6 | if(par[y] < par[x]) swap(x, y); 7 | par[x] += par[y]; 8 | par[y] = x; 9 | //int tmp=val[x]+val[y]; 10 | //val[x]=val[y]=tmp; 11 | //gans=max(gans,tmp); 12 | } 13 | } dsu; 14 | 15 | //Initially par[i]=-1 for all. 16 | //If each block has initial size (see TWOFL in cc) 17 | // -par[v]=size of block representing v. 18 | -------------------------------------------------------------------------------- /Delauney.cpp: -------------------------------------------------------------------------------- 1 | // Running time: O(n^4) 2 | // 3 | // INPUT: x[] = x-coordinates 4 | // y[] = y-coordinates 5 | // 6 | // OUTPUT: triples = a vector containing m triples of indices 7 | // corresponding to triangle vertices 8 | 9 | #include 10 | using namespace std; 11 | 12 | typedef double T; 13 | 14 | struct triple { 15 | int i, j, k; 16 | triple() {} 17 | triple(int i, int j, int k) : i(i), j(j), k(k) {} 18 | }; 19 | 20 | vector delaunayTriangulation(vector& x, vector& y) { 21 | int n = x.size(); 22 | vector z(n); 23 | vector ret; 24 | 25 | for (int i = 0; i < n; i++) 26 | z[i] = x[i] * x[i] + y[i] * y[i]; 27 | 28 | for (int i = 0; i < n-2; i++) { 29 | for (int j = i+1; j < n; j++) { 30 | for (int k = i+1; k < n; k++) { 31 | if (j == k) continue; 32 | double xn = (y[j]-y[i])*(z[k]-z[i]) - (y[k]-y[i])*(z[j]-z[i]); 33 | double yn = (x[k]-x[i])*(z[j]-z[i]) - (x[j]-x[i])*(z[k]-z[i]); 34 | double zn = (x[j]-x[i])*(y[k]-y[i]) - (x[k]-x[i])*(y[j]-y[i]); 35 | bool flag = zn < 0; 36 | for (int m = 0; flag && m < n; m++) 37 | flag = flag && ((x[m]-x[i])*xn + 38 | (y[m]-y[i])*yn + 39 | (z[m]-z[i])*zn <= 0); 40 | if (flag) ret.push_back(triple(i, j, k)); 41 | } 42 | } 43 | } 44 | return ret; 45 | } 46 | int main() { 47 | T xs[]={0, 0, 1, 0.9}; 48 | T ys[]={0, 1, 0, 0.9}; 49 | vector x(&xs[0], &xs[4]), y(&ys[0], &ys[4]); 50 | vector tri = delaunayTriangulation(x, y); 51 | 52 | //expected: 0 1 3 53 | // 0 3 2 54 | 55 | int i; 56 | for(i = 0; i < tri.size(); i++) printf("%d %d %d\n", tri[i].i, tri[i].j, tri[i].k); 57 | } 58 | -------------------------------------------------------------------------------- /Dynamic Convex Hull.cpp: -------------------------------------------------------------------------------- 1 | const ll is_query = -(1LL<<62); 2 | struct Line { 3 | ll m, b; 4 | mutable function succ; 5 | bool operator<(const Line& rhs) const { 6 | if (rhs.b != is_query) return m < rhs.m; 7 | const Line* s = succ(); 8 | if (!s) return 0; 9 | ll x = rhs.m; 10 | return b - s->b < (s->m - m) * x; 11 | } 12 | }; 13 | struct HullDynamic : public multiset { // will maintain upper hull for maximum 14 | bool bad(iterator y) { 15 | auto z = next(y); 16 | if (y == begin()) { 17 | if (z == end()) return 0; 18 | return y->m == z->m && y->b <= z->b; 19 | } 20 | auto x = prev(y); 21 | if (z == end()) return y->m == x->m && y->b <= x->b; 22 | return (x->b - y->b)*(z->m - y->m) >= (y->b - z->b)*(y->m - x->m); 23 | } 24 | void insert_line(ll m, ll b) { 25 | auto y = insert({ m, b }); 26 | y->succ = [=] { return next(y) == end() ? 0 : &*next(y); }; 27 | if (bad(y)) { erase(y); return; } 28 | while (next(y) != end() && bad(next(y))) erase(next(y)); 29 | while (y != begin() && bad(prev(y))) erase(prev(y)); 30 | } 31 | ll eval(ll x) { 32 | auto l = *lower_bound((Line) { x, is_query }); 33 | return l.m * x + l.b; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /FFT.cpp: -------------------------------------------------------------------------------- 1 | using cd = complex; 2 | const double PI = acos(-1); 3 | int reverse(int num, int lg_n) { 4 | int res = 0; 5 | for (int i = 0; i < lg_n; i++) if (num & (1 << i)) res |= 1 << (lg_n - 1 - i); 6 | return res; 7 | } 8 | void fft(vector & a, bool invert) { 9 | int n = a.size(); 10 | int lg_n = 0; 11 | while ((1 << lg_n) < n) lg_n++; 12 | for (int i = 0; i < n; i++) if (i < reverse(i, lg_n)) swap(a[i], a[reverse(i, lg_n)]); 13 | for (int len = 2; len <= n; len <<= 1) { 14 | double ang = 2 * PI / len * (invert ? -1 : 1); 15 | cd wlen(cos(ang), sin(ang)); 16 | for (int i = 0; i < n; i += len) { 17 | cd w(1); 18 | for (int j = 0; j < len / 2; j++) { 19 | cd u = a[i+j], v = a[i+j+len/2] * w; 20 | a[i+j] = u + v; 21 | a[i+j+len/2] = u - v; 22 | w *= wlen; 23 | } 24 | } 25 | } 26 | if (invert) { for (cd & x : a) x /= n;} 27 | } 28 | vector multiply(vector const& a, vector const& b) { 29 | vector fa(a.begin(), a.end()), fb(b.begin(), b.end()); 30 | int n = 1; 31 | while (n < a.size() + b.size()) n <<= 1; 32 | fa.resize(n);fb.resize(n); 33 | fft(fa, false);fft(fb, false); 34 | for (int i = 0; i < n; i++) fa[i] *= fb[i]; 35 | fft(fa, true); 36 | vector result(n); 37 | for (int i = 0; i < n; i++) result[i] = round(fa[i].real()); 38 | return result; 39 | } 40 | -------------------------------------------------------------------------------- /Graph Power Library.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | //COPY THE BLACKBOX, there is no need to change anything in it. 6 | //Check the main function at bottom for USAGE 7 | 8 | //****************BLACKBOX START***************** 9 | //START COPYING FROM HERE 10 | 11 | typedef int ll; 12 | 13 | class Graph { 14 | 15 | bool is_directed; 16 | 17 | public: 18 | vector>>adj; 19 | int n,N=2000000; 20 | Graph(int n_, bool is_directed_){ 21 | n=n_; is_directed = is_directed_; 22 | adj.resize(N,vector>()); 23 | } 24 | 25 | int hash(int u, int v){ 26 | return u*1873+v; 27 | } 28 | int hash(int u, int v, int k){ 29 | return k*1873*1873+u*1873+v; 30 | } 31 | bool node_has_edges(int u) { 32 | return (adj[u].size()!=0); 33 | } 34 | bool node_has_edges(int u, int v) { 35 | int x = hash(u,v); 36 | return (adj[x].size()!=0); 37 | } 38 | bool node_has_edges(int u, int v, int k) { 39 | int x = hash(u,v,k); 40 | return (adj[x].size()!=0); 41 | } 42 | 43 | void add_edge(int u, int v, ll c=0){ 44 | add_edge_weighted_undirected(u,v,c); 45 | if(!is_directed) 46 | add_edge_weighted_undirected(v,u,c); 47 | } 48 | void add_edge(int ui, int uj, int vi, int vj, ll c=0){ 49 | int u=hash(ui,uj), v=hash(vi,vj); 50 | add_edge_weighted_undirected(u,v,c); 51 | if(!is_directed) 52 | add_edge_weighted_undirected(v,u,c); 53 | } 54 | void add_edge(int ui, int uj,int uk, int vi, int vj, int vk, ll c=0){ 55 | int u=hash(ui,uj,uk), v=hash(vi,vj,vk); 56 | add_edge_weighted_undirected(u,v,c); 57 | if(!is_directed) 58 | add_edge_weighted_undirected(v,u,c); 59 | } 60 | 61 | private : 62 | 63 | void add_edge_weighted_undirected(int u, int v, ll c) { 64 | pairp = make_pair(v,c); 65 | adj[u].push_back(p); 66 | } 67 | 68 | }; 69 | 70 | class BFS { 71 | vectormin_dist_from_source; 72 | vector visited; 73 | 74 | public: 75 | BFS(Graph *g_) { 76 | g = g_; 77 | min_dist_from_source.resize(g->N,-1); 78 | visited.resize(g->N, false); 79 | } 80 | Graph *g; 81 | 82 | 83 | void run(int source) { 84 | queue q; 85 | q.push(source); 86 | 87 | visited[source] = true; 88 | min_dist_from_source[source] = 0; 89 | 90 | while(!q.empty()) { 91 | int cur_node = q.front(); 92 | for (unsigned int i = 0; i < (g->adj[cur_node]).size(); ++i) { 93 | int adj_node = (g->adj[cur_node])[i].first; 94 | if (visited[adj_node] == false) { 95 | visited[adj_node] = true; 96 | min_dist_from_source[adj_node] = min_dist_from_source[cur_node] + 1; 97 | q.push(adj_node); 98 | } 99 | } 100 | q.pop(); 101 | } 102 | 103 | return; 104 | } 105 | 106 | void run(int sourcei, int sourcej){ 107 | int source = (g->hash)(sourcei, sourcej); 108 | run(source); 109 | } 110 | void run(int sourcei, int sourcej, int sourcek){ 111 | int source = (g->hash)(sourcei, sourcej, sourcek); 112 | run(source); 113 | } 114 | 115 | int min_dist(int targeti, int targetj){ 116 | int target = (g->hash)(targeti,targetj); 117 | return min_dist_from_source[target]; 118 | } 119 | int min_dist(int targeti,int targetj,int targetk){ 120 | int target = (g->hash)(targeti,targetj,targetk); 121 | return min_dist_from_source[target]; 122 | } 123 | int min_dist(int target){ 124 | return min_dist_from_source[target]; 125 | } 126 | 127 | bool is_visisted(int targeti,int targetj){ 128 | int target = (g->hash)(targeti,targetj); 129 | return visited[target]; 130 | } 131 | bool is_visisted(int targeti,int targetj,int targetk){ 132 | int target = (g->hash)(targeti,targetj,targetk); 133 | return visited[target]; 134 | } 135 | bool is_visisted(int target){ 136 | return visited[target]; 137 | } 138 | 139 | }; 140 | //END COPYING HERE 141 | //********************BLACKBOX END****************** 142 | int main() { 143 | // initaitise a directed graph with 4 nodes, nodes are 0-indexed 144 | Graph g(4, true); 145 | // initaitise an un-directed graph with 4 nodes, nodes are 0-indexed 146 | Graph g(4, false); 147 | 148 | //DIRECTED GRAPH : add edges `Node 0 -> Node 4` and `Node 1 -> Node 3` 149 | g.add_edge(0,4); 150 | g.add_edge(1,3); 151 | 152 | //UNDIRECT GRAPH : add edges between `Node 0 -- Node 4` and `Node 1 -- Node 3` 153 | g.add_edge(0,4); 154 | g.add_edge(1,3); 155 | 156 | //DIRECTED GRAPH 2D (useful for grid problems): add edges `Node {0,1} -> Node {2,4}` and `Node {3,1} -> Node {3,3}` 157 | g.add_edge(0,1,2,4); 158 | g.add_edge(3,1,3,1); 159 | 160 | //UNDIRECT GRAPH 2D (useful for grid problems): add edges between `Node {0,1} -- Node {2,4}` and `Node {3,1} -- Node {3,3}` 161 | g.add_edge(0,1,2,4); 162 | g.add_edge(3,1,3,1); 163 | 164 | 165 | 166 | 167 | //*Do BFS on the graph g* 168 | BFS bfs(&g); 169 | 170 | //BFS on 1D Graph 171 | //start bfs on `Node 2` 172 | bfs.run(2); 173 | //get minimum distance of `Node 4` from source node (minimum distance is -1 if `Node 4` is unreacable from soure node) 174 | int min_d = bfs.min_dist(4); 175 | //check if `Node 4` is visited aka reachable from source node 176 | bool is_reachable = bfs.is_visisted(4); 177 | 178 | 179 | //BFS on 2D Graph 180 | //start bfs on `Node {1,4}` 181 | bfs.run(1,4); 182 | //get minimum distance of `Node {2,3}` from source node (minimum distance is -1 if `Node {2,3}` is unreacable from soure node) 183 | int min_d = bfs.min_dist(2,3); 184 | //check if `Node {2,3}` is visited aka reachable from source node 185 | bool is_reachable = bfs.is_visisted(2,3); 186 | 187 | 188 | 189 | return 0; 190 | } 191 | 192 | /*NOTES 193 | 1. [IMP for P2 & P4] If you call bfs.run again (even with a different source node), the previous run's minimum distance and visited is maintained 194 | 2. The Nodes are 0-indexed. 195 | */ 196 | -------------------------------------------------------------------------------- /GraphX.cpp: -------------------------------------------------------------------------------- 1 | 2 | //COPY THE BLACKBOX, there is no need to change anything in it. 3 | //Check the main function at bottom for USAGE 4 | 5 | //****************BLACKBOX START***************** 6 | //START COPYING FROM HERE 7 | 8 | typedef int ll; 9 | 10 | class Hash { 11 | private: 12 | map,int>hash_table; 13 | public: 14 | Hash () {} 15 | int hash(int x){ 16 | return hash({x,0,0}); 17 | } 18 | int hash(tuplex){ 19 | return hash({get<0>(x),get<1>(x),0}); 20 | } 21 | int hash(tuplex){ 22 | if(hash_table.find(x)!=hash_table.end()) 23 | return hash_table[x]; 24 | int new_hash = hash_table.size(); 25 | hash_table[x]=new_hash; 26 | return new_hash; 27 | } 28 | }; 29 | 30 | class Graph { 31 | 32 | bool is_directed; 33 | 34 | public: 35 | vector>>adj; 36 | int n,N=5000000; 37 | Hash h; 38 | 39 | Graph(int n_, bool is_directed_ = true){ 40 | n=n_; is_directed = is_directed_; 41 | adj.resize(N,vector>()); 42 | } 43 | 44 | int hash(int u, int v){ 45 | return h.hash({u,v}); 46 | } 47 | int hash(int u, int v, int k){ 48 | return h.hash({u,v,k}); 49 | } 50 | 51 | void add_edge(int uR, int vR, ll c=0){ 52 | int u=h.hash(uR), v=h.hash(vR); 53 | add_edge_internal(u,v,c); 54 | } 55 | void add_edge(tuple uR, tuple vR, ll c=0){ 56 | int u=h.hash(uR), v=h.hash(vR); 57 | add_edge_internal(u,v,c); 58 | } 59 | void add_edge(tuple uR, tuple vR, ll c=0){ 60 | int u=h.hash(uR), v=h.hash(vR); 61 | add_edge_internal(u,v,c); 62 | } 63 | 64 | 65 | private : 66 | 67 | void add_edge_internal(int u, int v, ll c=0){ 68 | add_edge_weighted_undirected(u,v,c); 69 | if(!is_directed) 70 | add_edge_weighted_undirected(v,u,c); 71 | } 72 | void add_edge_weighted_undirected(int u, int v, ll c) { 73 | pairp = make_pair(v,c); 74 | adj[u].push_back(p); 75 | } 76 | 77 | }; 78 | 79 | class BFS { 80 | vectormin_dist_from_source; 81 | vector visited; 82 | Graph *g; 83 | 84 | public: 85 | BFS(Graph *g_) { 86 | g = g_; 87 | clear(); 88 | } 89 | 90 | void clear() { 91 | min_dist_from_source.clear(); 92 | min_dist_from_source.resize(g->N,-1); 93 | visited.clear(); 94 | visited.resize(g->N, false); 95 | } 96 | 97 | 98 | void run(int sourceR) { 99 | int source = (g->h).hash(sourceR); 100 | run_internal(source); 101 | } 102 | void run(tuple sourceR) { 103 | int source = (g->h).hash(sourceR); 104 | run_internal(source); 105 | } 106 | void run(tuple sourceR) { 107 | int source = (g->h).hash(sourceR); 108 | run_internal(source); 109 | } 110 | 111 | 112 | int min_dist(int targetR){ 113 | int target = (g->h).hash(targetR); 114 | return min_dist_internal(target); 115 | } 116 | int min_dist(tuple targetR){ 117 | int target = (g->h).hash(targetR); 118 | return min_dist_internal(target); 119 | } 120 | int min_dist(tuple targetR){ 121 | int target = (g->h).hash(targetR); 122 | return min_dist_internal(target); 123 | } 124 | 125 | bool is_visited(int targetR){ 126 | int target = (g->h).hash(targetR); 127 | return is_visited_internal(target); 128 | } 129 | bool is_visited(tuple targetR){ 130 | int target = (g->h).hash(targetR); 131 | return is_visited_internal(target); 132 | } 133 | bool is_visited(tuple targetR){ 134 | int target = (g->h).hash(targetR); 135 | return is_visited_internal(target); 136 | } 137 | 138 | private: 139 | void run_internal(int source) { 140 | queue q; 141 | q.push(source); 142 | 143 | visited[source] = true; 144 | min_dist_from_source[source] = 0; 145 | 146 | while(!q.empty()) { 147 | int cur_node = q.front(); 148 | for (unsigned int i = 0; i < (g->adj[cur_node]).size(); ++i) { 149 | int adj_node = (g->adj[cur_node])[i].first; 150 | if (visited[adj_node] == false) { 151 | visited[adj_node] = true; 152 | min_dist_from_source[adj_node] = min_dist_from_source[cur_node] + 1; 153 | q.push(adj_node); 154 | } 155 | } 156 | q.pop(); 157 | } 158 | 159 | return; 160 | } 161 | 162 | int min_dist_internal(int target){ 163 | return min_dist_from_source[target]; 164 | } 165 | 166 | bool is_visited_internal(int target){ 167 | return visited[target]; 168 | } 169 | 170 | }; 171 | //END COPYING HERE 172 | //********************BLACKBOX END****************** 173 | -------------------------------------------------------------------------------- /HLD.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | #define root 0 6 | #define N 10100 7 | #define LN 14 8 | 9 | vector adj[N], costs[N], indexx[N]; 10 | int baseArray[N], ptr; 11 | int chainNo, chainInd[N], chainHead[N], posInBase[N]; 12 | int depth[N], pa[LN][N], otherEnd[N], subsize[N]; 13 | int st[N*6], qt[N*6]; 14 | 15 | /* 16 | * make_tree: 17 | * Used to construct the segment tree. It uses the baseArray for construction 18 | */ 19 | void make_tree(int cur, int s, int e) { 20 | if(s == e-1) { 21 | st[cur] = baseArray[s]; 22 | return; 23 | } 24 | int c1 = (cur<<1), c2 = c1 | 1, m = (s+e)>>1; 25 | make_tree(c1, s, m); 26 | make_tree(c2, m, e); 27 | st[cur] = st[c1] > st[c2] ? st[c1] : st[c2]; 28 | } 29 | 30 | /* 31 | * update_tree: 32 | * Point update. Update a single element of the segment tree. 33 | */ 34 | void update_tree(int cur, int s, int e, int x, int val) { 35 | if(s > x || e <= x) return; 36 | if(s == x && s == e-1) { 37 | st[cur] = val; 38 | return; 39 | } 40 | int c1 = (cur<<1), c2 = c1 | 1, m = (s+e)>>1; 41 | update_tree(c1, s, m, x, val); 42 | update_tree(c2, m, e, x, val); 43 | st[cur] = st[c1] > st[c2] ? st[c1] : st[c2]; 44 | } 45 | 46 | /* 47 | * query_tree: 48 | * Given S and E, it will return the maximum value in the range [S,E) 49 | */ 50 | void query_tree(int cur, int s, int e, int S, int E) { 51 | if(s >= E || e <= S) { 52 | qt[cur] = -1; 53 | return; 54 | } 55 | if(s >= S && e <= E) { 56 | qt[cur] = st[cur]; 57 | return; 58 | } 59 | int c1 = (cur<<1), c2 = c1 | 1, m = (s+e)>>1; 60 | query_tree(c1, s, m, S, E); 61 | query_tree(c2, m, e, S, E); 62 | qt[cur] = qt[c1] > qt[c2] ? qt[c1] : qt[c2]; 63 | } 64 | 65 | /* 66 | * query_up: 67 | * It takes two nodes u and v, condition is that v is an ancestor of u 68 | * We query the chain in which u is present till chain head, then move to next chain up 69 | * We do that way till u and v are in the same chain, we query for that part of chain and break 70 | */ 71 | 72 | int query_up(int u, int v) { 73 | if(u == v) return 0; // Trivial 74 | int uchain, vchain = chainInd[v], ans = -1; 75 | // uchain and vchain are chain numbers of u and v 76 | while(1) { 77 | uchain = chainInd[u]; 78 | if(uchain == vchain) { 79 | // Both u and v are in the same chain, so we need to query from u to v, update answer and break. 80 | // We break because we came from u up till v, we are done 81 | if(u==v) break; 82 | query_tree(1, 0, ptr, posInBase[v]+1, posInBase[u]+1); 83 | // Above is call to segment tree query function 84 | if(qt[1] > ans) ans = qt[1]; // Update answer 85 | break; 86 | } 87 | query_tree(1, 0, ptr, posInBase[chainHead[uchain]], posInBase[u]+1); 88 | // Above is call to segment tree query function. We do from chainHead of u till u. That is the whole chain from 89 | // start till head. We then update the answer 90 | if(qt[1] > ans) ans = qt[1]; 91 | u = chainHead[uchain]; // move u to u's chainHead 92 | u = pa[0][u]; //Then move to its parent, that means we changed chains 93 | } 94 | return ans; 95 | } 96 | 97 | /* 98 | * LCA: 99 | * Takes two nodes u, v and returns Lowest Common Ancestor of u, v 100 | */ 101 | int LCA(int u, int v) { 102 | if(depth[u] < depth[v]) swap(u,v); 103 | int diff = depth[u] - depth[v]; 104 | for(int i=0; i>i)&1 ) u = pa[i][u]; 105 | if(u == v) return u; 106 | for(int i=LN-1; i>=0; i--) if(pa[i][u] != pa[i][v]) { 107 | u = pa[i][u]; 108 | v = pa[i][v]; 109 | } 110 | return pa[0][u]; 111 | } 112 | 113 | void query(int u, int v) { 114 | /* 115 | * We have a query from u to v, we break it into two queries, u to LCA(u,v) and LCA(u,v) to v 116 | */ 117 | int lca = LCA(u, v); 118 | int ans = query_up(u, lca); // One part of path 119 | int temp = query_up(v, lca); // another part of path 120 | if(temp > ans) ans = temp; // take the maximum of both paths 121 | printf("%d\n", ans); 122 | } 123 | 124 | /* 125 | * change: 126 | * We just need to find its position in segment tree and update it 127 | */ 128 | void change(int i, int val) { 129 | int u = otherEnd[i]; 130 | update_tree(1, 0, ptr, posInBase[u], val); 131 | } 132 | 133 | /* 134 | * Actual HL-Decomposition part 135 | * Initially all entries of chainHead[] are set to -1. 136 | * So when ever a new chain is started, chain head is correctly assigned. 137 | * As we add a new node to chain, we will note its position in the baseArray. 138 | * In the first for loop we find the child node which has maximum sub-tree size. 139 | * The following if condition is failed for leaf nodes. 140 | * When the if condition passes, we expand the chain to special child. 141 | * In the second for loop we recursively call the function on all normal nodes. 142 | * chainNo++ ensures that we are creating a new chain for each normal child. 143 | */ 144 | void HLD(int curNode, int cost, int prev) { 145 | if(chainHead[chainNo] == -1) { 146 | chainHead[chainNo] = curNode; // Assign chain head 147 | } 148 | chainInd[curNode] = chainNo; 149 | posInBase[curNode] = ptr; // Position of this node in baseArray which we will use in Segtree 150 | baseArray[ptr++] = cost; 151 | 152 | int sc = -1, ncost; 153 | // Loop to find special child 154 | for(int i=0; i::max(); 3 | struct point {// point structure for 2D-tree, can be extended to 3D 4 | ntype x, y; 5 | point(ntype xx = 0, ntype yy = 0) : x(xx), y(yy) {} 6 | }; 7 | bool operator==(const point &a, const point &b) {return a.x == b.x && a.y == b.y;} 8 | bool on_x(const point &a, const point &b) {return a.x < b.x;} // sorts points on x-coordinate 9 | bool on_y(const point &a, const point &b) {return a.y < b.y;} // sorts points on y-coordinate 10 | ntype pdist2(const point &a, const point &b) {ntype dx = a.x-b.x, dy = a.y-b.y;return dx*dx + dy*dy;}// squared distance between points 11 | 12 | struct bbox{// bounding box for a set of points 13 | ntype x0, x1, y0, y1; 14 | bbox() : x0(sentry), x1(-sentry), y0(sentry), y1(-sentry) {} 15 | void compute(const vector &v) {// computes bounding box from a bunch of points 16 | for (int i = 0; i < v.size(); ++i) { 17 | x0 = min(x0, v[i].x); x1 = max(x1, v[i].x); 18 | y0 = min(y0, v[i].y); y1 = max(y1, v[i].y); 19 | } 20 | } 21 | ntype distance(const point &p) {// squared distance between a point and this bbox, 0 if inside 22 | if (p.x < x0) { 23 | if (p.y < y0) return pdist2(point(x0, y0), p); 24 | else if (p.y > y1) return pdist2(point(x0, y1), p); 25 | else return pdist2(point(x0, p.y), p); 26 | } 27 | else if (p.x > x1) { 28 | if (p.y < y0) return pdist2(point(x1, y0), p); 29 | else if (p.y > y1) return pdist2(point(x1, y1), p); 30 | else return pdist2(point(x1, p.y), p); 31 | } 32 | else { 33 | if (p.y < y0) return pdist2(point(p.x, y0), p); 34 | else if (p.y > y1) return pdist2(point(p.x, y1), p); 35 | else return 0; 36 | } 37 | } 38 | }; 39 | struct kdnode {// stores a single node of the kd-tree, either internal or leaf 40 | bool leaf; // true if this is a leaf node (has one point) 41 | point pt; // the single point of this is a leaf 42 | bbox bound; // bounding box for set of points in children 43 | kdnode *first, *second; // two children of this kd-node 44 | kdnode() : leaf(false), first(0), second(0) {} 45 | ~kdnode() { if (first) delete first; if (second) delete second; } 46 | ntype intersect(const point &p) {return bound.distance(p);}// intersect a point with this node (returns squared distance) 47 | void construct(vector &vp){ // recursively builds a kd-tree f1rom a given cloud of points 48 | bound.compute(vp); // compute bounding box for points at this node 49 | if (vp.size() == 1) {// if we're down to one point, then we're a leaf node 50 | leaf = true; 51 | pt = vp[0]; 52 | } 53 | else { 54 | // split on x if the bbox is wider than high (not best heuristic...) else // otherwise split on y-coordinate 55 | if (bound.x1-bound.x0 >= bound.y1-bound.y0) sort(vp.begin(), vp.end(), on_x); else sort(vp.begin(), vp.end(), on_y); 56 | // divide by taking half the array for each child(not best performance if many duplicates in the middle) 57 | int half = vp.size()/2; 58 | vector vl(vp.begin(), vp.begin()+half); 59 | vector vr(vp.begin()+half, vp.end()); 60 | first = new kdnode(); first->construct(vl); 61 | second = new kdnode(); second->construct(vr); 62 | } 63 | } 64 | }; 65 | struct kdtree{// simple kd-tree class to hold the tree and handle queries 66 | kdnode *root; 67 | kdtree(const vector &vp) {// constructs a kd-tree from a points (copied here, as it sorts them) 68 | vector v(vp.begin(), vp.end()); 69 | root = new kdnode(); 70 | root->construct(v); 71 | } 72 | ~kdtree() { delete root; } 73 | // recursive search method returns squared distance to nearest point 74 | ntype search(kdnode *node, const point &p){ 75 | if (node->leaf) { 76 | // commented special case tells a point not to find itself 77 | // if (p == node->pt) return sentry; 78 | // else 79 | return pdist2(p, node->pt); 80 | } 81 | ntype bfirst = node->first->intersect(p); 82 | ntype bsecond = node->second->intersect(p); 83 | // choose the side with the closest bounding box to search first 84 | // (note that the other side is also searched if needed) 85 | if (bfirst < bsecond) { 86 | ntype best = search(node->first, p); 87 | if (bsecond < best) best = min(best, search(node->second, p)); 88 | return best; 89 | } else { 90 | ntype best = search(node->second, p); 91 | if (bfirst < best) best = min(best, search(node->first, p)); 92 | return best; 93 | } 94 | } 95 | // squared distance to the nearest 96 | ntype nearest(const point &p) {return search(root, p);} 97 | }; 98 | int main() {// some basic test code here 99 | vector vp;// generate some random points for a kd-tree 100 | for (int i = 0; i < 100000; ++i) vp.push_back(point(rand()%100000, rand()%100000)); 101 | kdtree tree(vp); 102 | for (int i = 0; i < 10; ++i) {// query some points 103 | point q(rand()%100000, rand()%100000); 104 | cout<<"Closest squared distance to (" << q.x << ", " << q.y << ")"<< " is " << tree.nearest(q) << endl; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Matrix Determinant.cpp: -------------------------------------------------------------------------------- 1 | //N^3, can remove mods 2 | const ll mod = 12345; 3 | ll det(vector>& a) { 4 | int n = sz(a); ll ans = 1; 5 | rep(i,0,n) { 6 | rep(j,i+1,n) { 7 | while (a[j][i] != 0) { // gcd step 8 | ll t = a[i][i] / a[j][i]; 9 | if (t) rep(k,i,n) 10 | a[i][k] = (a[i][k] - a[j][k] * t) % mod; 11 | swap(a[i], a[j]); 12 | ans *= -1; 13 | } 14 | } 15 | ans = ans * a[i][i] % mod; 16 | if (!ans) return 0; 17 | } 18 | return (ans + mod) % mod; 19 | } 20 | -------------------------------------------------------------------------------- /Matrix Expo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Uses powers of two to exponentiate numbers and matrices. Calculates 3 | n^k in O(log(k)) time when n is a number. If A is an n x n matrix, 4 | calculates A^k in O(n^3*log(k)) time. 5 | */ 6 | #include 7 | using namespace std; 8 | typedef double T; 9 | typedef vector VT; 10 | typedef vector VVT; 11 | T power(T x, int k) { 12 | T ret = 1; 13 | while(k) { 14 | if(k & 1) ret *= x; 15 | k >>= 1; x *= x; 16 | } 17 | return ret; 18 | } 19 | VVT multiply(VVT& A, VVT& B) { 20 | int n = A.size(), m = A[0].size(), k = B[0].size(); 21 | VVT C(n, VT(k, 0)); 22 | 23 | for(int i = 0; i < n; i++) 24 | for(int j = 0; j < k; j++) 25 | for(int l = 0; l < m; l++) 26 | C[i][j] += A[i][l] * B[l][j]; 27 | 28 | return C; 29 | } 30 | VVT power(VVT& A, int k) { 31 | int n = A.size(); 32 | VVT ret(n, VT(n)), B = A; 33 | for(int i = 0; i < n; i++) ret[i][i]=1; 34 | while(k) { 35 | if(k & 1) ret = multiply(ret, B); 36 | k >>= 1; B = multiply(B, B); 37 | } 38 | return ret; 39 | } 40 | int main() { 41 | /* Expected Output: 42 | 2.37^48 = 9.72569e+17 43 | 376 264 285 220 265 44 | 550 376 529 285 484 45 | 484 265 376 264 285 46 | 285 220 265 156 264 47 | 529 285 484 265 376 */ 48 | double n = 2.37; int k = 48; 49 | cout << n << "^" << k << " = " << power(n, k) << endl; 50 | double At[5][5] = { 51 | { 0, 0, 1, 0, 0 }, 52 | { 1, 0, 0, 1, 0 }, 53 | { 0, 0, 0, 0, 1 }, 54 | { 1, 0, 0, 0, 0 }, 55 | { 0, 1, 0, 0, 0 } }; 56 | 57 | vector > A(5, vector (5)); 58 | for(int i = 0; i < 5; i++) 59 | for(int j = 0; j < 5; j++) 60 | A[i][j] = At[i][j]; 61 | 62 | vector > Ap = power(A, k); 63 | 64 | cout << endl; 65 | for(int i = 0; i < 5; i++) { 66 | for(int j = 0; j < 5; j++) 67 | cout << Ap[i][j] << " "; 68 | cout << endl; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Miller Rabin + mod_Mull.cpp: -------------------------------------------------------------------------------- 1 | /*Miller-Rabin primality probabilistic test. 2 | * Probability of failing one iteration is at most 1/4. 15 iterations should be enough for 50-bit numbers. 3 | * Time: 15 times the complexity of $a^b \mod c$. */ 4 | 5 | typedef unsigned long long ull; 6 | const int bits = 10; 7 | // if all numbers are less than 2^k, set bits = 64-k 8 | const ull po = 1 << bits; 9 | ull mod_mul(ull a, ull b, ull &c) { 10 | ull x = a * (b & (po - 1)) % c; 11 | while ((b >>= bits) > 0) { 12 | a = (a << bits) % c; 13 | x += (a * (b & (po - 1))) % c; 14 | } 15 | return x % c; 16 | } 17 | ull mod_pow(ull a, ull b, ull mod) { 18 | if (b == 0) return 1; 19 | ull res = mod_pow(a, b / 2, mod); 20 | res = mod_mul(res, res, mod); 21 | if (b & 1) return mod_mul(res, a, mod); 22 | return res; 23 | } 24 | bool prime(ull p) { //Rabin Miller 25 | if (p == 2) return true; 26 | if (p == 1 || p % 2 == 0) return false; 27 | ull s = p - 1; 28 | while (s % 2 == 0) s /= 2; 29 | rep(i,0,15) { 30 | ull a = rand() % (p - 1) + 1, tmp = s; 31 | ull mod = mod_pow(a, tmp, p); 32 | while (tmp != p - 1 && mod != 1 && mod != p - 1) { 33 | mod = mod_mul(mod, mod, p); 34 | tmp *= 2; 35 | } 36 | if (mod != p - 1 && tmp % 2 == 0) return false; 37 | } 38 | return true; 39 | } 40 | -------------------------------------------------------------------------------- /Min Vertex Cover.cpp: -------------------------------------------------------------------------------- 1 | /* Description: Finds a minimum vertex cover in a bipartite graph. 2 | * The size is the same as the size of a maximum matching, and 3 | * the complement is an independent set. 4 | * Status: fuzz-tested 5 | */ 6 | #pragma once 7 | 8 | #include "DFSMatching.h" 9 | 10 | vi cover(vector& g, int n, int m) { 11 | int res = dfs_matching(g, n, m); 12 | seen.assign(m, false); 13 | vector lfound(n, true); 14 | trav(it, match) if (it != -1) lfound[it] = false; 15 | vi q, cover; 16 | rep(i,0,n) if (lfound[i]) q.push_back(i); 17 | while (!q.empty()) { 18 | int i = q.back(); q.pop_back(); 19 | lfound[i] = 1; 20 | trav(e, g[i]) if (!seen[e] && match[e] != -1) { 21 | seen[e] = true; 22 | q.push_back(match[e]); 23 | } 24 | } 25 | rep(i,0,n) if (!lfound[i]) cover.push_back(i); 26 | rep(i,0,m) if (seen[i]) cover.push_back(n+i); 27 | assert(sz(cover) == res); 28 | return cover; 29 | } 30 | -------------------------------------------------------------------------------- /MinCostMaxFlow.cpp: -------------------------------------------------------------------------------- 1 | /* Min-cost max-flow. cap[i][j] != cap[j][i] is allowed; double edges are not. 2 | * If costs can be negative, call setpi before maxflow, but note that negative cost cycles are not supported. 3 | * To obtain the actual flow, look at positive values only. Time: Approximately O(E^2) */ 4 | /*INPUT: - graph, constructed using AddEdge() 5 | // - source 6 | // - sink 7 | // OUTPUT: - (maximum flow value, minimum cost value) 8 | // - To obtain the actual flow, look at positive values only*/ 9 | #include /** keep-include */ 10 | const ll INF = numeric_limits::max() / 4; typedef vector VL; 11 | struct MCMF { 12 | int N; 13 | vector ed, red; 14 | vector cap, flow, cost; 15 | vi seen; 16 | VL dist, pi; 17 | vector par; 18 | MCMF(int N) : 19 | N(N), ed(N), red(N), cap(N, VL(N)), flow(cap), cost(cap), 20 | seen(N), dist(N), pi(N), par(N) {} 21 | void addEdge(int from, int to, ll cap, ll cost) { 22 | this->cap[from][to] = cap; 23 | this->cost[from][to] = cost; 24 | ed[from].push_back(to); 25 | red[to].push_back(from); 26 | } 27 | void path(int s) { 28 | fill(all(seen), 0); 29 | fill(all(dist), INF); 30 | dist[s] = 0; ll di; 31 | __gnu_pbds::priority_queue> q; 32 | vector its(N); 33 | q.push({0, s}); 34 | auto relax = [&](int i, ll cap, ll cost, int dir) { 35 | ll val = di - pi[i] + cost; 36 | if (cap && val < dist[i]) { 37 | dist[i] = val; 38 | par[i] = {s, dir}; 39 | if (its[i] == q.end()) its[i] = q.push({-dist[i], i}); 40 | else q.modify(its[i], {-dist[i], i}); 41 | } 42 | }; 43 | while (!q.empty()) { 44 | s = q.top().second; q.pop(); 45 | seen[s] = 1; di = dist[s] + pi[s]; 46 | trav(i, ed[s]) if (!seen[i]) relax(i, cap[s][i] - flow[s][i], cost[s][i], 1); 47 | trav(i, red[s]) if (!seen[i]) relax(i, flow[i][s], -cost[i][s], 0); 48 | } 49 | rep(i,0,N) pi[i] = min(pi[i] + dist[i], INF); 50 | } 51 | pair maxflow(int s, int t) { 52 | ll totflow = 0, totcost = 0; 53 | while (path(s), seen[t]) { 54 | ll fl = INF; 55 | for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p) fl = min(fl, r ? cap[p][x] - flow[p][x] : flow[x][p]); 56 | totflow += fl; 57 | for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p) if (r) flow[p][x] += fl; else flow[x][p] -= fl; 58 | } 59 | rep(i,0,N) rep(j,0,N) totcost += cost[i][j] * flow[i][j]; 60 | return {totflow, totcost}; 61 | } // If some costs can be negative, call this[setpi()] before maxflow: 62 | void setpi(int s) { // (otherwise, leave this out) 63 | fill(all(pi), INF); pi[s] = 0; 64 | int it = N, ch = 1; ll v; 65 | while (ch-- && it--) rep(i,0,N) if (pi[i] != INF) trav(to, ed[i]) if (cap[i][to]) 66 | if ((v = pi[i] + cost[i][to]) < pi[to]) pi[to] = v, ch = 1; 67 | assert(it >= 0); // negative cost cycle 68 | } 69 | }; 70 | -------------------------------------------------------------------------------- /NTT.cpp: -------------------------------------------------------------------------------- 1 | 2 | // If p=c.2^k+1, then we need 2^k th root of unity 3 | // root= not generator, rather g^c , root of unity, root_1 is its inverse wrt mod, root_pw means 2^k 4 | // inverse(n,mod) is a function for modular inverse\ 5 | // for fft with arbitrary remainder, break coefficients into modulo sqrt(M), dont use CRT 6 | const int mod = 7340033; 7 | const int root = 5; 8 | const int root_1 = 4404020; 9 | const int root_pw = 1 << 20; 10 | 11 | void fft(vector & a, bool invert) { 12 | int n = a.size(); 13 | 14 | for (int i = 1, j = 0; i < n; i++) { 15 | int bit = n >> 1; 16 | for (; j & bit; bit >>= 1) 17 | j ^= bit; 18 | j ^= bit; 19 | 20 | if (i < j) 21 | swap(a[i], a[j]); 22 | } 23 | for (int len = 2; len <= n; len <<= 1) { 24 | int wlen = invert ? root_1 : root; 25 | for (int i = len; i < root_pw; i <<= 1) 26 | wlen = (int)(1LL * wlen * wlen % mod); 27 | 28 | for (int i = 0; i < n; i += len) { 29 | int w = 1; 30 | for (int j = 0; j < len / 2; j++) { 31 | int u = a[i+j], v = (int)(1LL * a[i+j+len/2] * w % mod); 32 | a[i+j] = u + v < mod ? u + v : u + v - mod; 33 | a[i+j+len/2] = u - v >= 0 ? u - v : u - v + mod; 34 | w = (int)(1LL * w * wlen % mod); 35 | } 36 | } 37 | } 38 | if (invert) { 39 | int n_1 = inverse(n, mod); 40 | for (int & x : a) 41 | x = (int)(1LL * x * n_1 % mod); 42 | } 43 | } 44 | vector multiply(vector const& a, vector const& b) { 45 | vector fa(a),fb(b) ; 46 | int n = 1; 47 | while (n < a.size() + b.size()) 48 | n <<= 1; 49 | fa.resize(n); 50 | fb.resize(n); 51 | 52 | fft(fa, false); 53 | fft(fb, false); 54 | for (int i = 0; i < n; i++) 55 | fa[i] = (fa[i]*1LL*fb[i])%mod; 56 | fft(fa, true); 57 | fa.resize(a.size()+b.size()-1) ; 58 | return fa; 59 | } 60 | -------------------------------------------------------------------------------- /Neeraj_FFT.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC target("popcnt") 2 | #pragma GCC optimize("tree-vectorize") 3 | #include 4 | using namespace std; 5 | unsigned long long a[64][3300], b[64][3300]; 6 | string s1, s2; 7 | int main(){ 8 | cin >> s1 >> s2; 9 | for (int i = 0; i < s1.size(); i++) { 10 | if (s1[i] == '0') continue; 11 | for (int j = 0; j < 64; j++) { 12 | if (i < j) continue; 13 | a[j][(i - j) / 64] |= 1ULL << (i - j) % 64; 14 | } 15 | } 16 | for (int i = 0; i < s2.size(); i++){ 17 | if (s2[i] == '0') continue; 18 | for (int j = 0; j < 64; j++) { 19 | if (i < j) continue; 20 | b[j][(i - j) / 64] |= 1ULL << (i - j) % 64; 21 | } 22 | } 23 | int q;cin >> q; 24 | while (q--) { 25 | unsigned p1, p2, len; 26 | cin >> p1 >> p2 >> len; 27 | int ans = 0; 28 | for (size_t i = 0; i < len / 64; i++) 29 | ans += __builtin_popcountll(a[p1 % 64][p1 / 64 + i] ^ b[p2 % 64][p2 / 64 + i]); 30 | for (size_t i = len / 64 * 64; i < len; i++) ans += s1[p1 + i] ^ s2[p2 + i]; 31 | printf("%d\n", ans); 32 | } 33 | } 34 | /////////////longest common substring+LCP_FUN///// 35 | #define f first 36 | #define s second 37 | int suf[500005],sar[500005][20],lcp[500005],lev=1,mul=1,n; 38 | int lcp_fun(int x,int y) { int ans=0; 39 | for(int k=lev-1;k>=0&&x,int> > ve; 44 | string s,v; 45 | cin>>s>>v; 46 | m = v.size(); 47 | s.pb('z'+1); 48 | for(i=0;i1) st++,cn1--; 65 | while(st= m && cn2>1) st++,cnt2--; 66 | // cout<0 && dist[to[e]]==-1){ 28 | q[tail] = to[e]; ++tail; 29 | dist[to[e]] = dist[v]+1; 30 | } 31 | } 32 | } 33 | return dist[s]!=-1; 34 | } 35 | int dfs(int v, int f){ 36 | if(v==t) return f; 37 | for(int &e = now[v];e!=-1;e = next[e]){ 38 | if(cap[e]>0 && dist[to[e]]==dist[v]-1){ 39 | int ret = dfs(to[e],min(f,cap[e])); 40 | if(ret>0){ 41 | cap[e] -= ret; 42 | cap[e^1] += ret; 43 | return ret; 44 | } 45 | } 46 | } 47 | return 0; 48 | } 49 | long long max_flow(int source, int sink){ 50 | s = source; t = sink; 51 | long long f = 0; 52 | int x; 53 | while(bfs()){ 54 | for(int i = 0;i > initial_cap, cap; 81 | vector vis, where; 82 | SimpleMaxFlow(int _n) { 83 | n = _n + 1; 84 | initial_cap = vector >(n, vector(n)); 85 | cap = vector >(n, vector(n)); 86 | } 87 | void addEdge(int a, int b, int c) {initial_cap[a][b] = cap[a][b] = c;} 88 | int dfs(int x, int f) { 89 | if(vis[x]) return 0; 90 | if(x == t) return f; 91 | vis[x] = 1; 92 | int ret = 0; 93 | for(int i = 0; i < n; ++i) if(!vis[i] && cap[x][i] > 0) { 94 | where[i] = x; 95 | ret = max(ret, dfs(i, min(f, cap[x][i]))); 96 | } 97 | return ret; 98 | } 99 | int dfs_aug() { 100 | vis = vector(n, 0); 101 | where = vector(n, -1); 102 | return dfs(s, oo); 103 | } 104 | int bfs_aug() { 105 | vis = vector(n, 0); 106 | where = vector(n, -1); 107 | queue > q; 108 | q.push(make_pair(s, oo)); 109 | vis[s] = 1; 110 | while(!q.empty()) { 111 | pair cur = q.front(); q.pop(); 112 | if(cur.fi == t) return cur.se; 113 | vis[cur.fi] = 1; 114 | for(int i = 0; i < n; ++i) if(cap[cur.fi][i] > 0 && !vis[i]) { 115 | where[i] = cur.fi; 116 | vis[i] = 1; 117 | q.push(make_pair(i, min(cur.se, cap[cur.fi][i]))); 118 | } 119 | } return 0; 120 | } 121 | int pfs_aug() { 122 | vis = vector(n, 0); 123 | where = vector(n, -1); 124 | priority_queue > pq; 125 | pq.push(make_pair(s, oo)); 126 | vis[s] = 1; 127 | while(!pq.empty()) { 128 | pair cur = pq.top(); pq.pop(); 129 | if(cur.fi == t) return cur.se; 130 | vis[cur.fi] = 1; 131 | for(int i = 0; i < n; ++i) if(cap[cur.fi][i] > 0 && !vis[i]) { 132 | where[i] = cur.fi; 133 | vis[i] = 1; 134 | pq.push(make_pair(i, min(cur.se, cap[cur.fi][i]))); 135 | } 136 | } return 0; 137 | } 138 | int flow(int _s, int _t) { 139 | s = _s; t = _t; int f = 0; 140 | while(int inc = pfs_aug()) { 141 | f += inc; 142 | int cur = t; 143 | while(where[cur] > -1) { 144 | cap[where[cur]][cur] -= inc; 145 | cap[cur][where[cur]] += inc; 146 | cur = where[cur]; 147 | } 148 | } return f; 149 | } 150 | /*void disp() { 151 | cerr << endl<< "Flow from " << s << " to " << t << endl; 152 | for(int i = 0; i < n; ++i) for(int j = 0; j < n; ++j) if(initial_cap[i][j] > 0) {cerr << i << " " << j << " " << cap[i][j] << "/" << initial_cap[i][j] << endl;} 153 | cerr << endl; 154 | }*/}; 155 | typedef vector vi; //////////////[HOPCRAFT]//////////////////// 156 | #define all(x) x.begin(), x.end() 157 | #define trav(a, x) for(auto& a : x) 158 | #define rep(i, a, b) for(int i = a; i < (b); ++i) 159 | #define sz(x) (int)(x).size() 160 | bool dfs_(int a,int layer,const vector& g,vi& btoa,vi& A,vi& B) { 161 | if (A[a] != layer) return 0; A[a] = -1; 162 | trav(b, g[a]) if (B[b] == layer + 1) {B[b] = -1; 163 | if (btoa[b]==-1 || dfs_(btoa[b],layer+2,g,btoa,A,B)) return btoa[b]=a,1;} 164 | return 0; 165 | } 166 | int hopcroftKarp(const vector& g, vi& btoa) { 167 | int res=0;vi A(g.size()), B(btoa.size()), cur, next; 168 | for (;;) { 169 | fill(all(A), 0); fill(all(B), -1); 170 | cur.clear();/// Find the starting nodes for BFS (i.e. layer 0). 171 | trav(a, btoa) if(a != -1) A[a] = -1; 172 | rep(a,0,sz(g)) if(A[a] == 0) cur.push_back(a); 173 | for (int lay=1;;lay+=2) {/// Find all layers using bfs. 174 | bool islast = 0;next.clear(); 175 | trav(a, cur) trav(b, g[a]) { 176 | if (btoa[b]==-1) B[b]=lay,islast=1; 177 | else if (btoa[b]!=a && B[b]==-1) B[b]=lay,next.push_back(btoa[b]); 178 | } 179 | if (islast) break; if (next.empty()) return res; 180 | trav(a,next) A[a]=lay+1; cur.swap(next); 181 | }/// Use dfs_ to scan for augmenting paths. 182 | rep(a,0,sz(g)) if(dfs_(a, 0, g, btoa, A, B)) ++res; 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /Policy BST.cpp: -------------------------------------------------------------------------------- 1 | #include // Common file 2 | #include // Including tree_order_statistics_node_update 3 | using namespace __gnu_pbds; 4 | struct cmp { 5 | bool operator() (const int& a, const int& b) const { 6 | return a T; 11 | 12 | T.find_by_order(k); // iterator to the k-th largest element (counting from zero) 13 | T.order_of_key(x); // no of elements strictly smaller than x 14 | -------------------------------------------------------------------------------- /Pollard Rho- Factors.cpp: -------------------------------------------------------------------------------- 1 | /*Pollard's rho algorithm. It is a probabilistic factorisation 2 | * algorithm, whose expected time complexity is good. Before you start using it, 3 | * run {\tt init(bits)}, where bits is the length of the numbers you use. 4 | * Returns factors of the input without duplicates. 5 | * Time: Expected running time should be good enough for 50-bit numbers. 6 | */ 7 | #include "ModMulLL.h" 8 | #include "MillerRabin.h" 9 | #include "eratosthenes.h" 10 | vector pr; 11 | ull f(ull a, ull n, ull &has) { 12 | return (mod_mul(a, a, n) + has) % n; 13 | } 14 | vector factor(ull d) { 15 | vector res; 16 | for (int i = 0; i < sz(pr) && pr[i]*pr[i] <= d; i++) 17 | if (d % pr[i] == 0) { 18 | while (d % pr[i] == 0) d /= pr[i]; 19 | res.push_back(pr[i]); 20 | } 21 | //d is now a product of at most 2 primes. 22 | if (d > 1) { 23 | if (prime(d)) 24 | res.push_back(d); 25 | else while (true) { 26 | ull has = rand() % 2321 + 47; 27 | ull x = 2, y = 2, c = 1; 28 | for (; c==1; c = __gcd((y > x ? y - x : x - y), d)) { 29 | x = f(x, d, has); 30 | y = f(f(y, d, has), d, has); 31 | } 32 | if (c != d) { 33 | res.push_back(c); d /= c; 34 | if (d != c) res.push_back(d); 35 | break; 36 | } 37 | } 38 | } 39 | return res; 40 | } 41 | void init(int bits) {//how many bits do we use? 42 | vi p = eratosthenes_sieve(1 << ((bits + 2) / 3)); 43 | pr.assign(all(p)); 44 | } 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algorithms-Notebook -------------------------------------------------------------------------------- /RabinKarp String Hash.cpp: -------------------------------------------------------------------------------- 1 | struct Hashs 2 | { 3 | vector hashs; 4 | vector pows; 5 | int P; 6 | int MOD; 7 | 8 | Hashs() {} 9 | 10 | Hashs(string &s, int P, int MOD) : P(P), MOD(MOD) 11 | { 12 | int n = s.size(); 13 | pows.resize(n+1, 0); 14 | hashs.resize(n+1, 0); 15 | pows[0] = 1; 16 | for(int i=n-1;i>=0;i--) 17 | { 18 | hashs[i]=(1LL * hashs[i+1] * P + s[i] - 'a' + 1) % MOD; 19 | pows[n-i]=(1LL * pows[n-i-1] * P) % MOD; 20 | } 21 | pows[n] = (1LL * pows[n-1] * P)%MOD; 22 | } 23 | int get_hash(int l, int r) 24 | { 25 | int ans=hashs[l] + MOD - (1LL*hashs[r+1]*pows[r-l+1])%MOD; 26 | ans%=MOD; 27 | return ans; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /Sieve with logN factor queries.cpp: -------------------------------------------------------------------------------- 1 | int lp [ 1000010 ] ; 2 | vector < int > pr ; 3 | void sieve(int N) { 4 | for ( int i = 2 ; i <= N ; ++ i ) { 5 | if ( lp [ i ] == 0 ) { 6 | lp [ i ] = i ; 7 | pr. push_back ( i ) ; 8 | } 9 | for ( int j = 0 ; j < ( int ) pr. size ( ) && pr [ j ] <= lp [ i ] && i * pr [ j ] <= N ; ++ j ) 10 | lp [ i * pr [ j ] ] = pr [ j ] ; 11 | } 12 | } 13 | 14 | void factorquery(int x) { 15 | cout<1 && x%y==0) x/=y; 19 | if (x<2) return; 20 | factorquery(x); 21 | } 22 | 23 | 24 | // sieve( N ); N<=10^7. Using lp[] we can prime factorize nos <=10^7 in O(log N) instead of usual O(sqrt(N)). 25 | -------------------------------------------------------------------------------- /SimpleGraphTemplate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | template 8 | class Graph { 9 | private: 10 | vector> adj_list; 11 | bool directed; 12 | 13 | public: 14 | Graph(int n, bool is_directed = false) : adj_list(n), directed(is_directed) {} 15 | 16 | void add_edge(const T& u, const T& v) { 17 | adj_list[u].push_back(v); 18 | if (!directed) { 19 | adj_list[v].push_back(u); 20 | } 21 | } 22 | 23 | vector bfs(const T& start, const vector& landmines) { 24 | vector distance(adj_list.size(), -1); 25 | distance[start] = 0; 26 | 27 | queue q; 28 | q.push(start); 29 | 30 | while (!q.empty()) { 31 | T current_node = q.front(); 32 | q.pop(); 33 | 34 | for (const T& neighbor : adj_list[current_node]) { 35 | if (distance[neighbor] == -1 && !landmines[neighbor]) { 36 | distance[neighbor] = distance[current_node] + 1; 37 | q.push(neighbor); 38 | } 39 | } 40 | } 41 | 42 | return distance; 43 | } 44 | }; 45 | 46 | int main() { 47 | int N, M; 48 | cin >> N >> M; 49 | 50 | int source, target; 51 | cin >> source >> target; 52 | 53 | vector landmines(N); 54 | for (int i = 0; i < N; ++i) { 55 | int has_landmine; 56 | cin >> has_landmine; 57 | landmines[i] = (has_landmine == 1); 58 | } 59 | 60 | Graph g(N, false); // Undirected graph 61 | 62 | for (int i = 0; i < M; ++i) { 63 | int u, v; 64 | cin >> u >> v; 65 | g.add_edge(u, v); 66 | } 67 | 68 | vector distances = g.bfs(source, landmines); 69 | 70 | cout << distances[target] << "\n"; 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /SimpleGraphTemplate.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | 4 | public class GraphTemplate { 5 | static class FastReader { 6 | private final InputStream in; 7 | private final byte[] buffer = new byte[1024]; 8 | private int ptr = 0; 9 | private int buflen = 0; 10 | 11 | public FastReader() { 12 | in = System.in; 13 | } 14 | 15 | private boolean hasNextByte() { 16 | if (ptr < buflen) { 17 | return true; 18 | } else { 19 | ptr = 0; 20 | try { 21 | buflen = in.read(buffer); 22 | } catch (IOException e) { 23 | e.printStackTrace(); 24 | } 25 | return buflen > 0; 26 | } 27 | } 28 | 29 | private int readByte() { 30 | return hasNextByte() ? buffer[ptr++] : -1; 31 | } 32 | 33 | private boolean isWhiteSpace(int c) { 34 | return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1; 35 | } 36 | 37 | public int nextInt() { 38 | int n = 0; 39 | boolean minus = false; 40 | int c; 41 | while ((c = readByte()) != -1 && isWhiteSpace(c)); 42 | if (c == '-') { 43 | minus = true; 44 | c = readByte(); 45 | } 46 | do { 47 | n = n * 10 + (c - '0'); 48 | } while ((c = readByte()) >= '0' && c <= '9'); 49 | return minus ? -n : n; 50 | } 51 | 52 | public String next() { 53 | StringBuilder sb = new StringBuilder(); 54 | int c; 55 | while ((c = readByte()) != -1 && isWhiteSpace(c)); 56 | do { 57 | sb.appendCodePoint(c); 58 | } while ((c = readByte()) != -1 && !isWhiteSpace(c)); 59 | return sb.toString(); 60 | } 61 | } 62 | 63 | static class Graph { 64 | private final List> adjList; 65 | private final int V; 66 | 67 | public Graph(int vertices) { 68 | this.V = vertices; 69 | adjList = new ArrayList<>(V); 70 | for (int i = 0; i < V; i++) { 71 | adjList.add(new ArrayList<>()); 72 | } 73 | } 74 | 75 | public void addEdge(int u, int v) { 76 | adjList.get(u).add(v); 77 | adjList.get(v).add(u); // Remove this line for directed graphs 78 | } 79 | 80 | // Returns an array with the shortest distances from the start node to all other nodes 81 | public int[] bfs(int start) { 82 | boolean[] visited = new boolean[V]; 83 | int[] distance = new int[V]; 84 | Arrays.fill(distance, -1); // -1 indicates that the node is not reachable 85 | 86 | Queue queue = new LinkedList<>(); 87 | queue.offer(start); 88 | visited[start] = true; 89 | distance[start] = 0; 90 | 91 | while (!queue.isEmpty()) { 92 | int current = queue.poll(); 93 | 94 | for (int neighbor : adjList.get(current)) { 95 | if (!visited[neighbor]) { 96 | visited[neighbor] = true; 97 | distance[neighbor] = distance[current] + 1; 98 | queue.offer(neighbor); 99 | } 100 | } 101 | } 102 | 103 | return distance; 104 | } 105 | } 106 | 107 | public static void main(String[] args) { 108 | FastReader fr = new FastReader(); 109 | PrintWriter out = new PrintWriter(System.out); 110 | 111 | int V = fr.nextInt(); // Number of vertices 112 | int E = fr.nextInt(); // Number of edges 113 | 114 | Graph graph = new Graph(V); 115 | 116 | for (int i = 0; i < E; i++) { 117 | int u = fr.nextInt(); 118 | int v = fr.nextInt(); 119 | graph.addEdge(u, v); 120 | } 121 | 122 | int start = fr.nextInt(); // Starting node for BFS 123 | 124 | int[] distances = graph.bfs(start); 125 | 126 | // Output the shortest distance to all nodes 127 | for (int i = 0; i < distances.length; i++) { 128 | out.println("Shortest distance from node " + start + " to node " + i + " is " + distances[i]); 129 | } 130 | 131 | out.close(); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /SimpleGraphTemplate.py: -------------------------------------------------------------------------------- 1 | from collections import deque, defaultdict 2 | 3 | class Graph: 4 | def __init__(self, directed=False): 5 | self.adj_list = defaultdict(list) 6 | self.directed = directed 7 | 8 | def add_edge(self, u, v): 9 | self.adj_list[u].append(v) 10 | if not self.directed: 11 | self.adj_list[v].append(u) 12 | 13 | def bfs(self, start): 14 | # Dictionary to store distance from start node 15 | distance = {node: float('inf') for node in self.adj_list} 16 | distance[start] = 0 17 | 18 | queue = deque([start]) 19 | 20 | while queue: 21 | current_node = queue.popleft() 22 | 23 | for neighbor in self.adj_list[current_node]: 24 | if distance[neighbor] == float('inf'): # Unvisited node 25 | distance[neighbor] = distance[current_node] + 1 26 | queue.append(neighbor) 27 | 28 | return distance 29 | 30 | def print_graph(self): 31 | for key, value in self.adj_list.items(): 32 | print(f"{key}: {value}") 33 | 34 | # Example usage: 35 | if __name__ == "__main__": 36 | g = Graph(directed=False) 37 | g.add_edge(1, 2) 38 | g.add_edge(1, 3) 39 | g.add_edge(2, 4) 40 | g.add_edge(3, 5) 41 | g.add_edge(4, 5) 42 | 43 | # Print the adjacency list (for debugging) 44 | g.print_graph() 45 | 46 | # Perform BFS starting from node 1 47 | distances = g.bfs(1) 48 | print("\nDistances from node 1:") 49 | for node, dist in distances.items(): 50 | print(f"Node {node}: Distance {dist}") 51 | -------------------------------------------------------------------------------- /Simplex.cpp: -------------------------------------------------------------------------------- 1 | // Two-phase simplex algorithm for solving linear programs of the form 2 | // 3 | // maximize c^T x 4 | // subject to Ax <= b 5 | // x >= 0 6 | // 7 | // INPUT: A -- an m x n matrix 8 | // b -- an m-dimensional vector 9 | // c -- an n-dimensional vector 10 | // x -- a vector where the optimal solution will be stored 11 | // 12 | // OUTPUT: value of the optimal solution (infinity if unbounded 13 | // above, nan if infeasible) 14 | // 15 | // To use this code, create an LPSolver object with A, b, and c as 16 | // arguments. Then, call Solve(x). 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace std; 25 | 26 | typedef long double DOUBLE; 27 | typedef vector VD; 28 | typedef vector VVD; 29 | typedef vector VI; 30 | 31 | const DOUBLE EPS = 1e-9; 32 | 33 | struct LPSolver { 34 | int m, n; 35 | VI B, N; 36 | VVD D; 37 | 38 | LPSolver(const VVD &A, const VD &b, const VD &c) : 39 | m(b.size()), n(c.size()), N(n + 1), B(m), D(m + 2, VD(n + 2)) { 40 | for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) D[i][j] = A[i][j]; 41 | for (int i = 0; i < m; i++) { B[i] = n + i; D[i][n] = -1; D[i][n + 1] = b[i]; } 42 | for (int j = 0; j < n; j++) { N[j] = j; D[m][j] = -c[j]; } 43 | N[n] = -1; D[m + 1][n] = 1; 44 | } 45 | 46 | void Pivot(int r, int s) { 47 | double inv = 1.0 / D[r][s]; 48 | for (int i = 0; i < m + 2; i++) if (i != r) 49 | for (int j = 0; j < n + 2; j++) if (j != s) 50 | D[i][j] -= D[r][j] * D[i][s] * inv; 51 | for (int j = 0; j < n + 2; j++) if (j != s) D[r][j] *= inv; 52 | for (int i = 0; i < m + 2; i++) if (i != r) D[i][s] *= -inv; 53 | D[r][s] = inv; 54 | swap(B[r], N[s]); 55 | } 56 | 57 | bool Simplex(int phase) { 58 | int x = phase == 1 ? m + 1 : m; 59 | while (true) { 60 | int s = -1; 61 | for (int j = 0; j <= n; j++) { 62 | if (phase == 2 && N[j] == -1) continue; 63 | if (s == -1 || D[x][j] < D[x][s] || D[x][j] == D[x][s] && N[j] < N[s]) s = j; 64 | } 65 | if (D[x][s] > -EPS) return true; 66 | int r = -1; 67 | for (int i = 0; i < m; i++) { 68 | if (D[i][s] < EPS) continue; 69 | if (r == -1 || D[i][n + 1] / D[i][s] < D[r][n + 1] / D[r][s] || 70 | (D[i][n + 1] / D[i][s]) == (D[r][n + 1] / D[r][s]) && B[i] < B[r]) r = i; 71 | } 72 | if (r == -1) return false; 73 | Pivot(r, s); 74 | } 75 | } 76 | 77 | DOUBLE Solve(VD &x) { 78 | int r = 0; 79 | for (int i = 1; i < m; i++) if (D[i][n + 1] < D[r][n + 1]) r = i; 80 | if (D[r][n + 1] < -EPS) { 81 | Pivot(r, n); 82 | if (!Simplex(1) || D[m + 1][n + 1] < -EPS) return -numeric_limits::infinity(); 83 | for (int i = 0; i < m; i++) if (B[i] == -1) { 84 | int s = -1; 85 | for (int j = 0; j <= n; j++) 86 | if (s == -1 || D[i][j] < D[i][s] || D[i][j] == D[i][s] && N[j] < N[s]) s = j; 87 | Pivot(i, s); 88 | } 89 | } 90 | if (!Simplex(2)) return numeric_limits::infinity(); 91 | x = VD(n); 92 | for (int i = 0; i < m; i++) if (B[i] < n) x[B[i]] = D[i][n + 1]; 93 | return D[m][n + 1]; 94 | } 95 | }; 96 | 97 | int main() { 98 | 99 | const int m = 4; 100 | const int n = 3; 101 | DOUBLE _A[m][n] = { 102 | { 6, -1, 0 }, 103 | { -1, -5, 0 }, 104 | { 1, 5, 1 }, 105 | { -1, -5, -1 } 106 | }; 107 | DOUBLE _b[m] = { 10, -4, 5, -5 }; 108 | DOUBLE _c[n] = { 1, -1, 0 }; 109 | 110 | VVD A(m); 111 | VD b(_b, _b + m); 112 | VD c(_c, _c + n); 113 | for (int i = 0; i < m; i++) A[i] = VD(_A[i], _A[i] + n); 114 | 115 | LPSolver solver(A, b, c); 116 | VD x; 117 | DOUBLE value = solver.Solve(x); 118 | 119 | cerr << "VALUE: " << value << endl; // VALUE: 1.29032 120 | cerr << "SOLUTION:"; // SOLUTION: 1.74194 0.451613 1 121 | for (size_t i = 0; i < x.size(); i++) cerr << " " << x[i]; 122 | cerr << endl; 123 | return 0; 124 | } 125 | -------------------------------------------------------------------------------- /SplitString+stoi.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | template 4 | void split(const string &s, char delim, Out result) { 5 | stringstream ss(s); 6 | string item; 7 | while (std::getline(ss, item, delim)) { 8 | *(result++) = item; 9 | } 10 | } 11 | 12 | vector split(const string &s, char delim) { 13 | vector elems; 14 | split(s, delim, back_inserter(elems)); 15 | return elems; 16 | } 17 | vector cur; 18 | int main() { 19 | cur=split("Hey|0|YO|5252",'|'); 20 | for (auto x:cur) { 21 | if (x[0]=='5') { 22 | cout< g[100010]; Works on disconnected undirected graph too 3 | #include 4 | #define pb push_back 5 | using namespace std; 6 | int u,v,n,m,timez; 7 | vector vis; 8 | vector g[100010],low,d,cutpoints; 9 | vector > bridges; 10 | void dfs_cutpoints(int x,int par=-1) { 11 | vis[x]=true; 12 | low[x]=d[x]=timez++; 13 | for (int i=0;i=d[x] && par!=-1) cutpoints.pb(x); 21 | } 22 | } 23 | if (par==-1 && g[x].size()>1) cutpoints.pb(x); 24 | } 25 | void find_cutpoints() { 26 | timez=0; 27 | vis.assign(n,false),low.assign(n,-1),d.assign(n,-1); 28 | for (int i=0;id[x]) bridges.pb(make_pair(x,g[x][i])); 41 | } 42 | } 43 | } 44 | void find_bridges() { 45 | timez=0; 46 | vis.assign(n,false),low.assign(n,-1),d.assign(n,-1); 47 | for (int i=0;ibridges[i].second) swap(bridges[i].first,bridges[i].second); 53 | sort(bridges.begin(),bridges.end()); 54 | } 55 | int main() {ios::sync_with_stdio(false);cin.tie(0); 56 | cin>>n>>m; 57 | for (int i=0;i>u>>v,g[u].pb(v),g[v].pb(u); 58 | find_cutpoints(); find_bridges(); outputsort(); 59 | cout<> (__builtin_ctz(v) + 1)); 8 | -------------------------------------------------------------------------------- /circle_tangent.cpp: -------------------------------------------------------------------------------- 1 | //Returns a pair of the two points on the circle with radius r centered around c whos tangent lines intersect p. If p lies within the circle NaN-points are returned. P is intended to be Point. The first point is the one to the right as seen from the p towards c. 2 | //usage : pair p = circleTangents(P(100,2),P(0,0),2); 3 | template 4 | pair circleTangents(const P &p, const P &c, double r) { 5 | P a = p-c; 6 | double x = r*r/a.dist2(), y = sqrt(x-x*x); 7 | return make_pair(c+a*x+a.perp()*y, c+a*x-a.perp()*y); 8 | } 9 | -------------------------------------------------------------------------------- /circum circle.cpp: -------------------------------------------------------------------------------- 1 | //The circumcirle of a triangle is the circle intersecting all three vertices. ccRadius returns the radius of the circle going through points A, B and C and ccCenter returns the center of the same circle. 2 | double ccRadius(const P& A, const P& B, const P& C) { 3 | return (B-A).dist()*(C-B).dist()*(A-C).dist()/ 4 | abs((B-A).cross(C-A))/2; 5 | } 6 | P ccCenter(const P& A, const P& B, const P& C) { 7 | P b = C-A, c = B-A; 8 | return A + (b*c.dist2()-c*b.dist2()).perp()/b.cross(c)/2; 9 | } 10 | -------------------------------------------------------------------------------- /dates.cpp: -------------------------------------------------------------------------------- 1 | // Routines for performing computations on dates. In these routines, 2 | // months are expressed as integers from 1 to 12, days are expressed 3 | // as integers from 1 to 31, and years are expressed as 4-digit 4 | // integers. 5 | 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | string dayOfWeek[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; 12 | 13 | // converts Gregorian date to integer (Julian day number) 14 | int dateToInt (int m, int d, int y){ 15 | return 16 | 1461 * (y + 4800 + (m - 14) / 12) / 4 + 17 | 367 * (m - 2 - (m - 14) / 12 * 12) / 12 - 18 | 3 * ((y + 4900 + (m - 14) / 12) / 100) / 4 + 19 | d - 32075; 20 | } 21 | 22 | // converts integer (Julian day number) to Gregorian date: month/day/year 23 | void intToDate (int jd, int &m, int &d, int &y){ 24 | int x, n, i, j; 25 | 26 | x = jd + 68569; 27 | n = 4 * x / 146097; 28 | x -= (146097 * n + 3) / 4; 29 | i = (4000 * (x + 1)) / 1461001; 30 | x -= 1461 * i / 4 - 31; 31 | j = 80 * x / 2447; 32 | d = x - 2447 * j / 80; 33 | x = j / 11; 34 | m = j + 2 - 12 * x; 35 | y = 100 * (n - 49) + i + x; 36 | } 37 | 38 | // converts integer (Julian day number) to day of week 39 | string intToDay (int jd){ 40 | return dayOfWeek[jd % 7]; 41 | } 42 | 43 | int main (int argc, char **argv){ 44 | int jd = dateToInt (3, 24, 2004); 45 | int m, d, y; 46 | intToDate (jd, m, d, y); 47 | string day = intToDay (jd); 48 | 49 | // expected output: 50 | // 2453089 51 | // 3/24/2004 52 | // Wed 53 | cout << jd << endl 54 | << m << "/" << d << "/" << y << endl 55 | << day << endl; 56 | } 57 | -------------------------------------------------------------------------------- /dfsmatching.cpp: -------------------------------------------------------------------------------- 1 | * Description: This is a simple matching algorithm but should 2 | * be just fine in most cases. Graph $g$ should be a list of 3 | * neighbours of the left partition. $n$ is the size of the left 4 | * partition and $m$ is the size of the right partition. 5 | * If you want to get the matched pairs, $match[i]$ contains 6 | * match for vertex $i$ on the right side or $-1$ if it's not 7 | * matched. 8 | * Time: O(EV) where $E$ is the number of edges and V is the number of vertices. 9 | * Status: works 10 | */ 11 | #pragma once 12 | 13 | vi match; 14 | vector seen; 15 | bool find(int j, const vector& g) { 16 | if (match[j] == -1) return 1; 17 | seen[j] = 1; int di = match[j]; 18 | trav(e, g[di]) 19 | if (!seen[e] && find(e, g)) { 20 | match[e] = di; 21 | return 1; 22 | } 23 | return 0; 24 | } 25 | int dfs_matching(const vector& g, int n, int m) { 26 | match.assign(m, -1); 27 | rep(i,0,n) { 28 | seen.assign(m, 0); 29 | trav(j,g[i]) 30 | if (find(j, g)) { 31 | match[j] = i; 32 | break; 33 | } 34 | } 35 | return m - (int)count(all(match), -1); 36 | } 37 | -------------------------------------------------------------------------------- /fraction class: -------------------------------------------------------------------------------- 1 | struct NOS { 2 | ll num,den; 3 | NOS() {} 4 | NOS(ll numn) : num(num) {den = 1;} 5 | NOS(ll num,ll den) : num(num),den(den) { 6 | ll G = __gcd(num, den); 7 | num /= G; 8 | den /= G; 9 | } 10 | NOS(const NOS &p) : num(p.num),den(p.den) {} 11 | NOS operator + (const NOS &p) const { 12 | ll num_=num*p.den+den*p.num,den_=den*p.den; 13 | ll G=__gcd(num_,den_); 14 | num_/=G; den_/=G; 15 | return NOS(num_,den_); 16 | } 17 | NOS operator - (const NOS &p) const { 18 | ll num_=num*p.den-den*p.num,den_=den*p.den; 19 | ll G=__gcd(num_,den_); 20 | num_/=G; den_/=G; 21 | return NOS(num_,den_); 22 | } 23 | NOS operator * (const NOS &p) const { 24 | ll a = num, b = den, c = p.num, d = p.den; 25 | ll G1 = __gcd(a, d), G2 = __gcd(b, c); 26 | a /= G1; d /= G1; 27 | b /= G2; c /= G2; 28 | a *= c; 29 | b *= d; 30 | ll G = __gcd(a, b); //extra 31 | a /= G; b /= G; //extra 32 | return NOS(a, b); 33 | } 34 | bool operator != (const NOS &p) const { 35 | return (p.num != num or p.den != den); 36 | } 37 | bool operator == (const NOS &p) const { 38 | return (p.num == num and p.den == den); 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /geometry.cpp: -------------------------------------------------------------------------------- 1 | double INF = 1e100; 2 | double EPS = 1e-12; 3 | const double PI = 3.14159265358979323846264338327950288419716939937510L; 4 | struct PT { 5 | double x, y; 6 | PT() {} 7 | PT(double x, double y) : x(x), y(y) {} 8 | PT(const PT &p) : x(p.x), y(p.y) {} 9 | PT operator + (const PT &p) const { return PT(x+p.x, y+p.y); } 10 | PT operator - (const PT &p) const { return PT(x-p.x, y-p.y); } 11 | PT operator * (double c) const { return PT(x*c, y*c ); } 12 | PT operator / (double c) const { return PT(x/c, y/c ); } 13 | bool operator<(const PT &rhs) const { return make_pair(y,x) < make_pair(rhs.y,rhs.x); } 14 | bool operator==(const PT &rhs) const { return make_pair(y,x) == make_pair(rhs.y,rhs.x); } 15 | }; 16 | 17 | double dot(PT p, PT q) { return p.x*q.x+p.y*q.y; } 18 | double dist2(PT p, PT q) { return dot(p-q,p-q); } 19 | double cross(PT p, PT q) { return p.x*q.y-p.y*q.x; } 20 | ostream &operator<<(ostream &os,const PT &p) {return os<<"("< 27 | #define REMOVE_REDUNDANT 28 | double area2(PT a, PT b, PT c) { return cross(a,b) + cross(b,c) + cross(c,a); } 29 | #ifdef REMOVE_REDUNDANT 30 | bool between(const PT &a, const PT &b, const PT &c) { 31 | return (fabs(area2(a,b,c)) < EPS && (a.x-b.x)*(c.x-b.x) <= 0 && (a.y-b.y)*(c.y-b.y) <= 0);} 32 | #endif 33 | void ConvexHull(vector &pts) { 34 | sort(pts.begin(), pts.end()); 35 | pts.erase(unique(pts.begin(), pts.end()), pts.end()); 36 | vector up, dn; 37 | for (int i = 0; i < pts.size(); i++) { 38 | while (up.size() > 1 && area2(up[up.size()-2], up.back(), pts[i]) >= 0) up.pop_back(); 39 | while (dn.size() > 1 && area2(dn[dn.size()-2], dn.back(), pts[i]) <= 0) dn.pop_back(); 40 | up.push_back(pts[i]); 41 | dn.push_back(pts[i]); 42 | } 43 | pts = dn; 44 | for (int i = (int) up.size() - 2; i >= 1; i--) pts.push_back(up[i]); 45 | #ifdef REMOVE_REDUNDANT 46 | if (pts.size() <= 2) return; 47 | dn.clear(); 48 | dn.push_back(pts[0]); 49 | dn.push_back(pts[1]); 50 | for (int i = 2; i < pts.size(); i++) { 51 | if (between(dn[dn.size()-2], dn[dn.size()-1], pts[i])) dn.pop_back(); 52 | dn.push_back(pts[i]); 53 | } 54 | if (dn.size() >= 3 && between(dn.back(), dn[0], dn[1])) { 55 | dn[0] = dn.back(); 56 | dn.pop_back(); 57 | } 58 | pts = dn; 59 | #endif 60 | } // 61 | 62 | // project point c onto line through a and b 63 | // assuming a != b 64 | PT ProjectPointLine(PT a, PT b, PT c) {return a + (b-a)*dot(c-a, b-a)/dot(b-a, b-a);} 65 | 66 | // project point c onto line segment through a and b 67 | PT ProjectPointSegment(PT a, PT b, PT c) { 68 | double r = dot(b-a,b-a); 69 | if (fabs(r) < EPS) return a; 70 | r = dot(c-a, b-a)/r; 71 | if (r < 0) return a; 72 | if (r > 1) return b; 73 | return a + (b-a)*r; 74 | } 75 | 76 | // reflection of point p on line ab 77 | PT PointReflectByLine(PT a,PT b,PT p) { 78 | PT ret=ProjectPointLine(a,b,p); 79 | return (ret+ret-p); 80 | } 81 | 82 | // compute distance from c to segment between a and b 83 | double DistancePointSegment(PT a,PT b,PT c){return sqrt(dist2(c,ProjectPointSegment(a,b,c)));} 84 | // compute distance between point (x,y,z) and plane ax+by+cz=d 85 | double DistancePointPlane(double x, double y, double z, 86 | double a, double b, double c, double d) { 87 | return fabs(a*x+b*y+c*z-d)/sqrt(a*a+b*b+c*c); 88 | } 89 | 90 | // determine if lines from a to b and c to d are parallel or collinear 91 | bool LinesParallel(PT a, PT b, PT c, PT d) { return fabs(cross(b-a, c-d)) < EPS; } 92 | 93 | bool LinesCollinear(PT a, PT b, PT c, PT d) { 94 | return LinesParallel(a, b, c, d) 95 | && fabs(cross(a-b, a-c)) < EPS 96 | && fabs(cross(c-d, c-a)) < EPS; 97 | } 98 | 99 | // determine if line segment from a to b intersects with 100 | // line segment from c to d 101 | bool SegmentsIntersect(PT a, PT b, PT c, PT d) { 102 | if (LinesCollinear(a, b, c, d)) { 103 | if (dist2(a, c) < EPS || dist2(a, d) < EPS || 104 | dist2(b, c) < EPS || dist2(b, d) < EPS) return true; 105 | if (dot(c-a, c-b) > 0 && dot(d-a, d-b) > 0 && dot(c-b, d-b) > 0) 106 | return false; 107 | return true; 108 | } 109 | if (cross(d-a, b-a) * cross(c-a, b-a) > 0) return false; 110 | if (cross(a-c, d-c) * cross(b-c, d-c) > 0) return false; 111 | return true; 112 | } 113 | 114 | // compute intersection of line passing through a and b 115 | // with line passing through c and d, assuming that unique 116 | // intersection exists; for segment intersection, check if 117 | // segments intersect first 118 | PT ComputeLineIntersection(PT a, PT b, PT c, PT d) { 119 | b=b-a; d=c-d; c=c-a; 120 | assert(dot(b, b) > EPS && dot(d, d) > EPS); 121 | return a + b*cross(c, d)/cross(b, d); 122 | } 123 | 124 | // compute center of circle given three points 125 | PT ComputeCircleCenter(PT a, PT b, PT c) { 126 | b=(a+b)/2; 127 | c=(a+c)/2; 128 | return ComputeLineIntersection(b, b+RotateCW90(a-b), c, c+RotateCW90(a-c)); 129 | } 130 | 131 | // determine if point is in a possibly non-convex polygon (by William 132 | // Randolph Franklin); returns 1 for strictly interior points, 0 for 133 | // strictly exterior points, and 0 or 1 for the remaining points. 134 | // Note that it is possible to convert this into an *exact* test using 135 | // integer arithmetic by taking care of the division appropriately 136 | // (making sure to deal with signs properly) and then by writing exact 137 | // tests for checking point on polygon boundary 138 | bool PointInPolygon(const vector &p, PT q) { 139 | bool c = 0; 140 | for (int i = 0; i < p.size(); i++){ 141 | int j = (i+1)%p.size(); 142 | if ((p[i].y <= q.y && q.y < p[j].y || 143 | p[j].y <= q.y && q.y < p[i].y) && 144 | q.x < p[i].x + (p[j].x - p[i].x) * (q.y - p[i].y) / (p[j].y - p[i].y)) 145 | c = !c; 146 | } 147 | return c; 148 | } 149 | 150 | // determine if point is on the boundary of a polygon 151 | bool PointOnPolygon(const vector &p, PT q) { 152 | for (int i = 0; i < p.size(); i++) 153 | if (dist2(ProjectPointSegment(p[i], p[(i+1)%p.size()], q), q) < EPS) return true; 154 | return false; 155 | } 156 | 157 | // is point a on segment bc 158 | bool PointOnSegment(PT a,PT b,PT c) { 159 | if (!LinesParallel(a,b,a,c)) return false; 160 | if (b.x<=a.x && a.x<=c.x) return true; 161 | if (c.x<=a.x && a.x<=b.x) return true; 162 | return false; 163 | } 164 | 165 | // compute intersection of line through points a and b with 166 | // circle centered at c with radius r > 0 167 | vector CircleLineIntersection(PT a, PT b, PT c, double r) { 168 | vector ret; 169 | b = b-a; 170 | a = a-c; 171 | double A = dot(b, b); 172 | double B = dot(a, b); 173 | double C = dot(a, a) - r*r; 174 | double D = B*B - A*C; 175 | if (D < -EPS) return ret; 176 | ret.push_back(c+a+b*(-B+sqrt(D+EPS))/A); 177 | if (D > EPS) 178 | ret.push_back(c+a+b*(-B-sqrt(D))/A); 179 | return ret; 180 | } 181 | // compute intersection of circle centered at a with radius r 182 | // with circle centered at b with radius R 183 | vector CircleCircleIntersection(PT a, PT b, double r, double R) { 184 | vector ret; 185 | double d = sqrt(dist2(a, b)); 186 | if (d > r+R || d+min(r, R) < max(r, R)) return ret; 187 | double x = (d*d-R*R+r*r)/(2*d); 188 | double y = sqrt(r*r-x*x); 189 | PT v = (b-a)/d; 190 | ret.push_back(a+v*x + RotateCCW90(v)*y); 191 | if (y > 0) ret.push_back(a+v*x - RotateCCW90(v)*y); 192 | return ret; 193 | } 194 | 195 | // This code computes the area or centroid of a (possibly nonconvex) 196 | // polygon, assuming that the coordinates are listed in a clockwise or 197 | // counterclockwise fashion. Note that the centroid is often known as 198 | // the "center of gravity" or "center of mass". 199 | double ComputeSignedArea(const vector &p) { 200 | double area = 0; 201 | for(int i = 0; i < p.size(); i++) { 202 | int j = (i+1) % p.size(); 203 | area += p[i].x*p[j].y - p[j].x*p[i].y; 204 | } 205 | return area / 2.0; 206 | } 207 | 208 | double ComputeArea(const vector &p) {return fabs(ComputeSignedArea(p));} 209 | 210 | PT ComputeCentroid(const vector &p) { 211 | PT c(0,0); 212 | double scale = 6.0 * ComputeSignedArea(p); 213 | for (int i = 0; i < p.size(); i++){ 214 | int j = (i+1) % p.size(); 215 | c = c + (p[i]+p[j])*(p[i].x*p[j].y - p[j].x*p[i].y); 216 | } 217 | return c / scale; 218 | } 219 | // tests whether or not a given polygon (in CW or CCW order) is simple 220 | bool IsSimple(const vector &p) { 221 | for (int i = 0; i < p.size(); i++) { 222 | for (int k = i+1; k < p.size(); k++) { 223 | int j = (i+1) % p.size(); 224 | int l = (k+1) % p.size(); 225 | if (i == l || j == k) continue; 226 | if (SegmentsIntersect(p[i], p[j], p[k], p[l])) 227 | return false; 228 | } 229 | } 230 | return true; 231 | } 232 | -------------------------------------------------------------------------------- /manacher.cpp: -------------------------------------------------------------------------------- 1 | Description: For each position in a string, computes p[0][i] = half length of 2 | * longest even palindrome around pos i, p[1][i] = longest odd (half rounded down). 3 | * Time: O(N) */ 4 | void manacher(const string& s) { 5 | int n = sz(s); 6 | vi p[2] = {vi(n+1), vi(n)}; 7 | rep(z,0,2) for (int i=0,l=0,r=0; i < n; i++) { 8 | int t = r-i+!z; 9 | if (i=1 && R+1r) l=L, r=R; 14 | }} 15 | -------------------------------------------------------------------------------- /nCr with mod precompute.cpp: -------------------------------------------------------------------------------- 1 | long long fact[N], ifact[N], inv[N]; 2 | void _pre() { 3 | fact[1] = fact[0] = 1; ifact[0] = ifact[1] = 1; inv[0] = inv[1] = 1; 4 | for (int i = 1; i < N; ++i) fact[i] = (fact[i - 1] * i) % mod; 5 | for (int i = 2; i < N; ++i) inv[i] = (((-(mod / i) * inv[mod % i]) % mod) + mod) % mod; 6 | for (int i = 2; i < N; ++i) ifact[i] = (ifact[i - 1] * inv[i]) % mod; 7 | } 8 | long long C(int n, int k) { 9 | if (k > n) return 0; 10 | if (n < 0 || k < 0) return 0; 11 | return (fact[n] * ((ifact[n - k] * ifact[k]) % mod)) % mod; 12 | } 13 | -------------------------------------------------------------------------------- /phi.cpp: -------------------------------------------------------------------------------- 1 | const int LIM = 5000000; int phi[LIM]; 2 | void calculatePhi() { 3 | rep(i,0,LIM) phi[i] = i&1 ? i : i/2; 4 | for(int i = 3; i < LIM; i += 2) if(phi[i] == i) 5 | for(int j = i; j < LIM; j += i) phi[j] -= phi[j] / i; 6 | } 7 | //Mobius Inversion : Let required be {sum_of_g=1-to-Gmax}h(g)*cnt[g] 8 | //Then h(g)={sum_of_d:d|g}f(d) //f(n)={sum_of_d:d|n}f(d)*mobius(n/d) 9 | FOR(i,1,n) for (int j=1;j<=n;j+=i) f[j] += h[i] * µ[j/i]; 10 | void preprocess() { // Compute mobius fucntion mu[] 11 | FOR(i,1,111100) mu[i]=primechk[i]=1;primechk[1]=0; 12 | FOR(i,2,111100) { 13 | if(primechk[i]==0) continue; 14 | mu[i]=-mu[i]; 15 | for (int j=2;i*j<=111100;j++) primechk[i*j]=0,mu[i*j]=(j%i==0?0:mu[i*j]=-mu[i*j]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /point in poly log N.cpp: -------------------------------------------------------------------------------- 1 | struct point {lint x,y;} pa[M],pb[M]; 2 | lint na,nb; 3 | lint isleft(point A,point B,point C) { 4 | return (ll(B.x-A.x)*ll(C.y-A.y)-ll(C.x-A.x)*ll(B.y-A.y)); 5 | } 6 | bool pt_in_poly(point p) { 7 | int a=1,b=na-1,c; 8 | if (isleft(pa[0],pa[a],pa[b])<=0) swap(a,b); 9 | if (isleft(pa[0],pa[a],p)<=0 || isleft(pa[0],pa[b],p)>=0) return false; 10 | while (abs(a-b)>1) { 11 | c=(a+b)/2; 12 | if (isleft(pa[0],pa[c],p)<=0) b=c; else a=c; 13 | } 14 | return (isleft(pa[a],pa[b],p)>0); 15 | } 16 | int main() { 17 | cin>>na; 18 | for (int i=0;i>pa[i].x>>pa[i].y; 19 | cin>>nb; 20 | for (int i=0;i>pb[i].x>>pb[i].y; 21 | for (int i=0;i 4 | #include 5 | 6 | int main() 7 | { 8 | std::random_device rd; //Will be used to obtain a seed for the random number engine 9 | std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd() 10 | 11 | //Various range distributions 12 | std::uniform_int_distribution<> dis(1, 6); 13 | std::uniform_real_distribution<> dis(1.0, 2.0); 14 | 15 | std::geometric_distribution<> d; // same as std::negative_binomial_distribution<> d(1, 0.5); 16 | 17 | // if particles decay once per second on average, 18 | // how much time, in seconds, until the next one? 19 | std::exponential_distribution<> d(1); //This is the continuous counterpart of geometric_distribution 20 | 21 | // values near the mean are the most likely 22 | // standard deviation affects the dispersion of generated values from the mean 23 | std::normal_distribution<> d{5,2}; //5 is mean, dispersion from mean is at range +/-2 24 | 25 | 26 | for (int n=0; n<10; ++n) 27 | //Use dis to transform the random unsigned int generated by gen into an int in [1, 6] 28 | std::cout << dis(gen) << ' '; 29 | std::cout << '\n'; 30 | } 31 | 32 | /* 33 | int main() 34 | { 35 | std::random_device rd; 36 | std::mt19937 gen(rd()); 37 | // perform 4 trials, each succeeds 1 in 2 times 38 | std::binomial_distribution<> d(4, 0.5); 39 | 40 | std::map hist; 41 | for (int n = 0; n < 10000; ++n) { 42 | ++hist[d(gen)]; 43 | } 44 | for (auto p : hist) { 45 | std::cout << p.first << ' ' 46 | << std::string(p.second/100, '*') << '\n'; 47 | } 48 | } 49 | */ 50 | -------------------------------------------------------------------------------- /spherical distance.cpp: -------------------------------------------------------------------------------- 1 | double sphericalDistance(double f1, double t1, 2 | double f2, double t2, double radius) { 3 | double dx = sin(t2)*cos(f2) - sin(t1)*cos(f1); 4 | double dy = sin(t2)*sin(f2) - sin(t1)*sin(f1); 5 | double dz = cos(t2) - cos(t1); 6 | double d = sqrt(dx*dx + dy*dy + dz*dz); 7 | return radius*2*asin(d/2); 8 | } 9 | -------------------------------------------------------------------------------- /ternary search.cpp: -------------------------------------------------------------------------------- 1 | /*Find the smallest i in $[a,b]$ that maximizes $f(i)$, assuming that $f(a) < \dots < f(i) \ge \dots \ge f(b)$. 2 | * To reverse which of the sides allows non-strict inequalities, change the < marked with (A) to <=, and reverse the loop at (B). 3 | * To minimize $f$, change it to >, also at (B). 4 | * Status: tested 5 | * Usage: 6 | int ind = ternSearch(0,n-1,[\&](int i){return a[i];}); 7 | * Time: O(\log(b-a)) 8 | */ 9 | 10 | template 11 | int ternSearch(int a, int b, F f) { 12 | assert(a <= b); 13 | while (b - a >= 5) { 14 | int mid = (a + b) / 2; 15 | if (f(mid) < f(mid+1)) // (A) 16 | a = mid; 17 | else 18 | b = mid+1; 19 | } 20 | rep(i,a+1,b+1) if (f(a) < f(i)) a = i; // (B) 21 | return a; 22 | } 23 | -------------------------------------------------------------------------------- /treap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define ll long long 4 | typedef struct node { 5 | struct node *l,*r; 6 | ll size,lazy,sum,val,prior; 7 | }node; 8 | 9 | typedef node* pnode; 10 | pnode head; 11 | 12 | ll sz(pnode t) { 13 | return t?t->size:0; 14 | } 15 | 16 | void upd_sz(pnode t) { 17 | if(t) t->size = sz(t->l)+1+sz(t->r); 18 | } 19 | 20 | void lazy(pnode t) { 21 | if(!t || !t->lazy) return; 22 | t->val += t->lazy; 23 | t->sum += t->lazy*sz(t); 24 | if(t->l) t->l->lazy += t->lazy; 25 | if(t->r) t->r->lazy += t->lazy; 26 | t->lazy = 0; 27 | } 28 | 29 | void reset(pnode t) { 30 | if(!t) return; 31 | t->sum = t->val; 32 | } 33 | 34 | void combine(pnode &t,pnode l,pnode r) { 35 | if(!l || !r) return void (t=l?l:r); 36 | t->sum = l->sum+r->sum; 37 | } 38 | 39 | void operation(pnode t) { 40 | if(!t) return; 41 | reset(t); 42 | lazy(t->l);lazy(t->r); 43 | combine(t,t->l,t); 44 | combine(t,t,t->r); 45 | } 46 | 47 | void split(pnode t,pnode &l,pnode &r,ll pos,ll add=0) { 48 | if(!t) return void(l = r = NULL); 49 | ll cur_pos = add + sz(t->l); 50 | lazy(t); 51 | if(cur_pos <= pos) split(t->r,t->r,r,pos,cur_pos+1),l=t; 52 | else split(t->l,l,t->l,pos,add),r=t; 53 | upd_sz(t); 54 | operation(t); 55 | } 56 | void merge(pnode &t,pnode l,pnode r) { 57 | lazy(l);lazy(r); 58 | if(!l || !r) t=l?l:r; 59 | else if(l->prior > r->prior) merge(l->r,l->r,r),t=l; 60 | else merge(r->l,l,r->l),t=r; 61 | upd_sz(t); 62 | operation(t); 63 | } 64 | 65 | void init(pnode t,ll val) { 66 | t->l = t->r = NULL; 67 | t->val = t->sum = val; 68 | t->size = 1,t->lazy=0; 69 | t->prior = rand(); 70 | } 71 | 72 | void range_update(pnode t,ll l,ll r,ll val) { 73 | pnode L,mid,R; 74 | split(t,L,mid,l-1); 75 | split(mid,t,R,r-l); 76 | t->lazy += val; 77 | merge(mid,L,t); 78 | merge(t,mid,R); 79 | } 80 | 81 | ll range_query(pnode t,ll l,ll r) { 82 | pnode L,mid,R; 83 | split(t,L,mid,l-1); 84 | split(mid,t,R,r-l); 85 | ll ans=t->sum; 86 | merge(mid,L,t); 87 | merge(t,mid,R); 88 | return ans; 89 | } 90 | 91 | int main() { 92 | ll t; 93 | cin>>t; 94 | while(t--) { 95 | ll i,j,k,l,n,m; 96 | cin>>n>>m; 97 | for(i=0;i>j>>k>>l; 107 | if(j) 108 | cout<>j; 111 | range_update(head,k-1,l-1,j); 112 | } 113 | } 114 | } 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /unordered_map for pair as key: -------------------------------------------------------------------------------- 1 | struct hash_pair { 2 | template 3 | size_t operator()(const pair& p) const 4 | { 5 | auto hash1 = hash{}(p.first); 6 | auto hash2 = hash{}(p.second); 7 | 8 | if (hash1 != hash2) { 9 | return hash1 ^ hash2; 10 | } 11 | 12 | // If hash1 == hash2, their XOR is zero. 13 | return hash1; 14 | } 15 | }; 16 | 17 | int main() { 18 | unordered_map, int, hash_pair> yo; 19 | } 20 | --------------------------------------------------------------------------------