├── README.md ├── Extra.cpp ├── Grundy Number (Nim Game).cpp ├── Logical CF Problems.cpp ├── Random Generator.cpp ├── 2 Pointers (Two Pointers).cpp ├── Floyd Warshall.cpp ├── FFT Applications.cpp ├── Bridges in Graph.cpp ├── DFS - Cycle Detection in Directed Graph.cpp ├── Factorials with nCr.cpp ├── Sparse Matrix (RMQ).cpp ├── Topological Sort.cpp ├── Hashing (Strings).cpp ├── Z Algorithm.cpp ├── Ordered Statistic Tree (PBDS).cpp ├── BFS 2D.cpp ├── SPFA.cpp ├── BFS.cpp ├── Centroid Decomposition.cpp ├── Intervals Handling.cpp ├── Gaussian Elimination.cpp ├── Prim's MST.cpp ├── 2 Closest Points in 2D Plane (N log^2 N).cpp ├── Geometry.cpp ├── Primitive Root.cpp ├── LCA (with Time Traversal DFS).cpp ├── Hungarian.cpp ├── Strongly Connected Component.cpp ├── polynomialInverse.cpp ├── FFT (Recursive).cpp ├── Kruskal's MST.cpp ├── Mo's Algorithm.cpp ├── Parallel Binary Search.cpp ├── 2-SAT.cpp ├── Bridge Tree in Graph.cpp ├── DSU (Disjoint Set Union).cpp ├── KMP.cpp ├── Matching (Hopcroft-Karp) in Bipartite Graph.cpp ├── Persistent Segment Tree.cpp ├── Extended Euclidean Algorithm (Extensive).cpp ├── Trie.cpp ├── Tree Construction with Specific Vertices.cpp ├── DSU On Trees.cpp ├── Matrix Struct.cpp ├── Negative Cycles in Directed Graph.cpp ├── Biconnected Components (Online Bridge).cpp ├── Convex Hull (Graham's Scan).cpp ├── BIT - Binary Indexed Tree (Fenwick Tree).cpp ├── NTT (Recursive).cpp ├── Dijkstra.cpp ├── Discrete Logarithm.cpp ├── MaxFlow - Push Relabel [V^2 sqrt(E)].cpp ├── suffixArray.cpp ├── SQRT Decomposition.cpp ├── Convex Hull (Dynamic).cpp ├── Min Cost Max Flow - Dijkstra.cpp ├── Segment Tree.cpp ├── MaxFlow - Push Relabel [V^3].cpp ├── FFT_jatin.cpp ├── Extra ├── Treap.cpp ├── Heavy Light Decomposition (HLD).cpp ├── Sweep Line: Intersecting Line Segments.cpp ├── FFT (Iterative).cpp └── Geo Snippet.cpp /README.md: -------------------------------------------------------------------------------- 1 | # Competitive-Coding 2 | -------------------------------------------------------------------------------- /Extra.cpp: -------------------------------------------------------------------------------- 1 | - DFS in 2D Grid: 2 | 3 | //Problem 1: https://codeforces.com/contest/616/problem/C 4 | //Solution 1: https://codeforces.com/contest/616/submission/45959489 5 | -------------------------------------------------------------------------------- /Grundy Number (Nim Game).cpp: -------------------------------------------------------------------------------- 1 | //Problem 1 (Prefix Nim): https://codeforces.com/contest/88/problem/E 2 | //Solution 1: https://codeforces.com/contest/88/submission/45960116 3 | -------------------------------------------------------------------------------- /Logical CF Problems.cpp: -------------------------------------------------------------------------------- 1 | http://codeforces.com/problemset/problem/844/D 2 | https://codeforces.com/problemset/problem/389/E 3 | https://codeforces.com/problemset/problem/450/E 4 | https://codeforces.com/contest/549/problem/C 5 | -------------------------------------------------------------------------------- /Random Generator.cpp: -------------------------------------------------------------------------------- 1 | //Source: http://codeforces.com/blog/entry/61587 2 | 3 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 4 | 5 | int getRand(int l, int r) 6 | { 7 | uniform_int_distribution uid(l, r); 8 | return uid(rng); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /2 Pointers (Two Pointers).cpp: -------------------------------------------------------------------------------- 1 | //Problem 1 (Frequency Match): https://codeforces.com/contest/701/problem/C 2 | //Solution 1: https://codeforces.com/contest/701/submission/45452242 3 | 4 | //Problem 2 (Moving pointer when violating condition): https://codeforces.com/contest/514/problem/D 5 | //Solution 2: https://codeforces.com/contest/514/submission/45492951 6 | -------------------------------------------------------------------------------- /Floyd Warshall.cpp: -------------------------------------------------------------------------------- 1 | int dist[N][N]; 2 | 3 | void FloydWarshall() 4 | { 5 | for(int k=1;k<=n;k++) 6 | for(int i=1;i<=n;i++) 7 | for(int j=1;j<=n;j++) 8 | dist[i][j]=min(dist[i][j], dist[i][k] + dist[k][j]); 9 | } 10 | 11 | //Problem 1: https://codeforces.com/contest/189/problem/D 12 | //Solution 1: https://codeforces.com/contest/189/submission/48938763 13 | -------------------------------------------------------------------------------- /FFT Applications.cpp: -------------------------------------------------------------------------------- 1 | 1) String Matching - Hamming Distance: 2 | 3 | // Logic: http://codeforces.com/blog/entry/59386 4 | 5 | void work(char ch1, char ch2) 6 | { 7 | int n=a.size(), m=b.size(); 8 | vector poly1(n, 0), poly2(n, 0); 9 | for(int i=0;i res; 14 | do_FFT(poly1, poly2, res); 15 | for(int i=m-1;i<=n+m-1;i++) 16 | ans[i]+=res[i]; 17 | } 18 | 19 | //Problem 1: https://www.spoj.com/problems/ADAMATCH/ 20 | //Solution 1: http://p.ip.fi/2K6S 21 | 22 | //Problem 2: https://codeforces.com/gym/101667/ : Problem H 23 | //Solution 2: http://p.ip.fi/dzmX 24 | -------------------------------------------------------------------------------- /Bridges in Graph.cpp: -------------------------------------------------------------------------------- 1 | int tim=0; 2 | int u[N], v[N], vis[N]; 3 | int tin[N], tout[N], isBridge[M], minAncestor[N]; 4 | vector > g[N]; //vertex, index of edge 5 | 6 | void dfs(int k, int par) 7 | { 8 | vis[k]=1; 9 | tin[k]=++tim; 10 | minAncestor[k]=tin[k]; 11 | for(auto it:g[k]) 12 | { 13 | if(it.first==par) 14 | continue; 15 | if(vis[it.first]) 16 | { 17 | minAncestor[k]=min(minAncestor[k], tin[it.first]); 18 | continue; 19 | } 20 | dfs(it.first, k); 21 | minAncestor[k]=min(minAncestor[k], minAncestor[it.first]); 22 | if(minAncestor[it.first]>tin[k]) 23 | isBridge[it.second]=1; 24 | } 25 | tout[k]=tim; 26 | } 27 | 28 | //Sample Problem 1: https://www.spoj.com/problems/EC_P/ 29 | //Sample Solution 1: http://p.ip.fi/shDA 30 | -------------------------------------------------------------------------------- /DFS - Cycle Detection in Directed Graph.cpp: -------------------------------------------------------------------------------- 1 | bool findLoop(int v) 2 | { 3 | if(vis[v]==1) 4 | return 1; 5 | if(vis[v]==2) 6 | return 0; 7 | vis[v]=1; 8 | for(auto &it:g[v]) 9 | { 10 | if(findLoop(it)) 11 | return 1; 12 | } 13 | vis[v]=2; 14 | return 0; 15 | } 16 | 17 | bool checkLoop() 18 | { 19 | fill(vis+1, vis+n+1, 0); 20 | for(int i=1;i<=n;i++) 21 | { 22 | if(!vis[i] && findLoop(i)) 23 | return 1; 24 | } 25 | return 0; 26 | } 27 | 28 | //Problem 1 (Marking edges belong to a cycle): https://codeforces.com/contest/915/problem/D 29 | //Solution 1: https://codeforces.com/contest/915/submission/41311663 30 | 31 | //Problem 2: https://codeforces.com/contest/937/problem/D 32 | //Solution 2: https://codeforces.com/contest/937/submission/45960040 33 | -------------------------------------------------------------------------------- /Factorials with nCr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace atcoder; 3 | //using mint = modint998244353; 4 | //using mint = modint1000000007; 5 | std::ostream& operator << (std::ostream& out, const mint& rhs) { 6 | return out< fac,inv; 12 | 13 | mint nCr(lli n,lli r) 14 | { 15 | if(n<0||r<0||r>n) 16 | return 0; 17 | return fac[n]*inv[r]*inv[n-r]; 18 | } 19 | 20 | void pre(lli n) 21 | { 22 | fac[0]=1; 23 | for(int i=1;i<=n;++i) 24 | fac[i]=i*fac[i-1]; 25 | inv[n]=fac[n].pow(mint(-2).val()); 26 | for(int i=n;i>0;--i) 27 | inv[i-1]=i*inv[i]; 28 | assert(inv[0]==mint(1)); 29 | } 30 | -------------------------------------------------------------------------------- /Sparse Matrix (RMQ).cpp: -------------------------------------------------------------------------------- 1 | //O(1) query sparse matrix for Max/Min/GCD 2 | 3 | int RMQ[20][N]; 4 | 5 | void precompute() 6 | { 7 | for(int i=0;(1<=1;i--) 14 | { 15 | RMQ[0][i]=dp[i]; 16 | int mxj=floorlog[n-i+1]; //2^j <= n-i+1 17 | int pw=1; 18 | for(int j=1;j<=mxj;j++) 19 | { 20 | RMQ[j][i]=max(RMQ[j-1][i], RMQ[j-1][i+pw]); 21 | pw<<=1; 22 | } 23 | } 24 | } 25 | 26 | int getMax(int L, int R) 27 | { 28 | int k=floorlog[R-L+1]; //2^k <= R-L+1 29 | return max(RMQ[k][L], RMQ[k][R - (1< topo; //Stores lexicographically smallest toposort 4 | vector g[N]; 5 | 6 | bool toposort() //Returns 1 if there exists a toposort, 0 if there is a cycle 7 | { 8 | priority_queue, greater > pq; 9 | for(int i=1;i<=n;i++) 10 | for(auto &it:g[i]) 11 | indeg[it]++; 12 | for(int i=1;i<=n;i++) 13 | { 14 | if(!indeg[i]) 15 | pq.push(i); 16 | } 17 | while(!pq.empty()) 18 | { 19 | int u=pq.top(); 20 | pq.pop(); 21 | topo.push_back(u); 22 | for(auto &v:g[u]) 23 | { 24 | indeg[v]--; 25 | if(!indeg[v]) 26 | pq.push(v); 27 | } 28 | } 29 | if(topo.size() hashs; 4 | vector pows; 5 | lli P; 6 | lli MOD; 7 | 8 | Hashs() {} 9 | 10 | Hashs(string &s, lli P, lli MOD) : P(P), MOD(MOD) 11 | { 12 | lli n = s.size(); 13 | pows.resize(n+1, 0); 14 | hashs.resize(n+1, 0); 15 | pows[0] = 1; 16 | for(lli 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 | lli get_hash(lli l, lli r) 24 | { 25 | lli ans=hashs[l] + MOD - (1LL*hashs[r+1]*pows[r-l+1])%MOD; 26 | ans%=MOD; 27 | return ans; 28 | } 29 | }; 30 | 31 | //Problem 1: https://codeforces.com/contest/633/problem/C 32 | //Solution 1: https://codeforces.com/contest/633/submission/42330829 33 | -------------------------------------------------------------------------------- /Z Algorithm.cpp: -------------------------------------------------------------------------------- 1 | //Logic = https://cp-algorithms.com/string/z-function.html 2 | 3 | //The Z-function for this string is an array of length n where the i-th element is equal to the greatest number 4 | //of characters starting from the position i that coincide with the first characters of s. 5 | 6 | vector z_function(string &s) 7 | { 8 | int n=s.size(); 9 | vector z(n); 10 | for(int i=1,l=0,r=0;ir) 17 | l=i, r=i+z[i]-1; 18 | } 19 | return z; 20 | } 21 | 22 | //Sample Problem 1: http://codeforces.com/problemset/problem/127/D 23 | //Sample Solution 1: http://codeforces.com/contest/127/submission/39791421 24 | 25 | //Sample Problem 2: http://codeforces.com/contest/432/problem/D 26 | //Sample Solution 2: http://codeforces.com/contest/432/submission/39791526 27 | -------------------------------------------------------------------------------- /Ordered Statistic Tree (PBDS).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include 5 | #include 6 | using namespace __gnu_pbds; 7 | 8 | #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); 9 | #define endl "\n" 10 | #define int long long 11 | 12 | const int N=2e5+5; 13 | 14 | #define T pair 15 | #define ordered_set tree, rb_tree_tag, tree_order_statistics_node_update> 16 | 17 | int getless(ordered_set &os, int R, int index) 18 | { 19 | return os.order_of_key({R, index}); 20 | } 21 | 22 | ordered_set os1; 23 | 24 | //Problem 1 (PBDS with int): https://codeforces.com/contest/1042/problem/D 25 | //Solution 1: https://codeforces.com/contest/1042/submission/42975984 26 | 27 | //Problem 2 (PBDS with rational): https://csacademy.com/contest/round-75/task/race-cars/ 28 | //Solution 2: http://p.ip.fi/cYCx 29 | -------------------------------------------------------------------------------- /BFS 2D.cpp: -------------------------------------------------------------------------------- 1 | int vis[N][N], dist[N][N], ways[N][N]; 2 | int dx[4]={-1, +1, 0, 0}; 3 | int dy[4]={0, 0, +1, -1}; 4 | 5 | void bfs(int x, int y, int n, int m) 6 | { 7 | queue > q; 8 | q.push({x, y}); 9 | ways[x][y]=1; 10 | vis[x][y]=1; 11 | dist[x][y]=0; 12 | while(!q.empty()) 13 | { 14 | int x=q.front().first; 15 | int y=q.front().second; 16 | q.pop(); 17 | for(int dir=0;dir<4;dir++) 18 | { 19 | int nx=x+dx[dir]; 20 | int ny=y+dy[dir]; 21 | if(nx<1 || ny<1 || nx>n || ny>m) 22 | continue; 23 | if(!vis[nx][ny]) 24 | { 25 | dist[nx][ny]=dist[x][y]+1; 26 | vis[nx][ny]=1; 27 | ways[nx][ny]+=ways[x][y]; 28 | q.push({nx, ny}); 29 | } 30 | else 31 | { 32 | if(dist[x][y] + 1 == dist[nx][ny]) 33 | ways[nx][ny]+=ways[x][y]; 34 | } 35 | } 36 | } 37 | } 38 | 39 | //Problem 1: https://www.spoj.com/problems/CLEANRBT/ 40 | //Solution 1: http://p.ip.fi/2fxO 41 | -------------------------------------------------------------------------------- /SPFA.cpp: -------------------------------------------------------------------------------- 1 | const int INF=1e9; 2 | 3 | int n, m; 4 | int dist[N], cnt[N]; 5 | bool inqueue[N]; 6 | vector > g[N]; 7 | 8 | bool SPFA(int source) //Returns true if there is a negative cycle reachable from source 9 | { 10 | queue q; 11 | 12 | for(int i=1;i<=n;i++) 13 | { 14 | cnt[i]=0; 15 | dist[i]=INF; 16 | } 17 | 18 | dist[source]=0; 19 | q.push(source); 20 | inqueue[source]=true; 21 | 22 | while(!q.empty()) 23 | { 24 | int v=q.front(); 25 | q.pop(); 26 | inqueue[v]=false; 27 | 28 | for(auto &edge:g[v]) 29 | { 30 | int to=edge.first; 31 | int w=edge.second; 32 | 33 | if(dist[v] + w < dist[to]) 34 | { 35 | dist[to] = dist[v] + w; 36 | dist[to] = max(dist[to], -INF); 37 | if(!inqueue[to]) 38 | { 39 | q.push(to); 40 | inqueue[to]=true; 41 | cnt[to]++; 42 | if(cnt[to]>n) 43 | return true; 44 | } 45 | } 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /BFS.cpp: -------------------------------------------------------------------------------- 1 | //Distance stores levels, and ways stores the number of ways to get from kth vertex to any other vertex with the shortest path taken 2 | 3 | int vis[N], dist[N], ways[N]; 4 | vector g[N]; 5 | 6 | void bfs(int k) 7 | { 8 | queue q; 9 | q.push(k); 10 | ways[k]=1; 11 | vis[k]=1; 12 | while(!q.empty()) 13 | { 14 | int node=q.front(); 15 | q.pop(); 16 | for(auto it:g[node]) 17 | { 18 | if(!vis[it]) 19 | { 20 | dist[it]=dist[node]+1; 21 | vis[it]=1; 22 | ways[it]+=ways[node]; 23 | q.push(it); 24 | } 25 | else 26 | { 27 | if(dist[node]+1==dist[it]) 28 | { 29 | ways[it]+=ways[node]; 30 | } 31 | } 32 | } 33 | } 34 | } 35 | 36 | 37 | //Problem 1: https://codeforces.com/contest/208/problem/C 38 | //Solution 1: https://codeforces.com/contest/208/submission/38315030 39 | 40 | //Problem 2 (Multiple of number not containing some digits): https://www.spoj.com/problems/MULTII/ 41 | //Solution 2: http://p.ip.fi/li3d 42 | -------------------------------------------------------------------------------- /Centroid Decomposition.cpp: -------------------------------------------------------------------------------- 1 | int subtree[N], parentcentroid[N]; 2 | set g[N]; 3 | 4 | void dfs(int k, int par) 5 | { 6 | nodes++; 7 | subtree[k]=1; 8 | for(auto it:g[k]) 9 | { 10 | if(it==par) 11 | continue; 12 | dfs(it, k); 13 | subtree[k]+=subtree[it]; 14 | } 15 | } 16 | 17 | int centroid(int k, int par) 18 | { 19 | for(auto it:g[k]) 20 | { 21 | if(it==par) 22 | continue; 23 | if(subtree[it]>(nodes>>1)) 24 | return centroid(it, k); 25 | } 26 | return k; 27 | } 28 | 29 | void decompose(int k, int par) 30 | { 31 | nodes=0; 32 | dfs(k, k); 33 | int node=centroid(k, k); 34 | parentcentroid[node]=par; 35 | for(auto it:g[node]) 36 | { 37 | g[it].erase(node); 38 | decompose(it, node); 39 | } 40 | } 41 | 42 | //Problem 1: https://codeforces.com/contest/322/problem/E 43 | //Solution 1: https://codeforces.com/contest/322/submission/45791742 44 | 45 | //Problem 2: https://codeforces.com/contest/342/problem/E 46 | //Solution 2: https://codeforces.com/contest/342/problem/E 47 | 48 | -------------------------------------------------------------------------------- /Intervals Handling.cpp: -------------------------------------------------------------------------------- 1 | map active; 2 | 3 | void init() 4 | { 5 | active[-1] = -1; 6 | active[2e9] = 2e9; 7 | active[1] = n; 8 | } 9 | 10 | void add(int L, int R) //Always remove [L, R] before adding 11 | { 12 | active[L]=R; 13 | ans+=R-L+1; 14 | } 15 | 16 | void remove(int L, int R) 17 | { 18 | int removed=0; 19 | auto it = active.lower_bound(L); 20 | it--; 21 | if(it->second>=L) 22 | { 23 | active[L] = it->second; 24 | it->second = L-1; 25 | } 26 | it++; 27 | while(it->first <= R) 28 | { 29 | if(it->second > R) 30 | { 31 | removed+=R + 1 - it->first; 32 | active[R+1] = it->second; 33 | } 34 | else 35 | removed+= it->second - it->first + 1; 36 | auto it2=it; 37 | it++; 38 | active.erase(it2); 39 | } 40 | ans-=removed; 41 | } 42 | 43 | //Problem 1: https://codeforces.com/contest/915/problem/E 44 | //Solution 1: https://codeforces.com/contest/915/submission/40028187 45 | 46 | //Problem 2 (with sets): https://codeforces.com/contest/899/problem/E 47 | //Solution 2: https://codeforces.com/contest/899/submission/45963607 48 | -------------------------------------------------------------------------------- /Gaussian Elimination.cpp: -------------------------------------------------------------------------------- 1 | // Credits @tfg 2 | //https://codeforces.com/contest/1100/submission/48339644 3 | 4 | struct Gauss { 5 | static const lli me = 62; 6 | lli table[me]; 7 | 8 | Gauss() { 9 | for(lli i = 0; i < me; i++) { 10 | table[i] = 0; 11 | } 12 | } 13 | 14 | lli size() { 15 | lli ans = 0; 16 | for(lli i = 0; i < me; i++) { 17 | if(table[i]) ans++; 18 | } 19 | return ans; 20 | } 21 | 22 | bool can(lli x) { 23 | for(lli i = me-1; i >= 0; i--) { 24 | x = std::min(x, x ^ table[i]); 25 | } 26 | return x == 0; 27 | } 28 | 29 | void add(lli x) { 30 | for(lli i = me-1; i >= 0 && x; i--) { 31 | if(table[i] == 0) { 32 | table[i] = x; 33 | x = 0; 34 | } else { 35 | x = std::min(x, x ^ table[i]); 36 | } 37 | } 38 | } 39 | 40 | lli best() { 41 | lli x = 0; 42 | for(lli i = me-1; i >= 0; i--) { 43 | x = std::max(x, x ^ table[i]); 44 | } 45 | return x; 46 | } 47 | 48 | void merge(Gauss &other) 49 | { 50 | for(lli i = me-1; i >= 0; i--) 51 | add(other.table[i]); 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /Prim's MST.cpp: -------------------------------------------------------------------------------- 1 | //Logic: https://www.hackerearth.com/practice/algorithms/graphs/minimum-spanning-tree/tutorial/ 2 | 3 | int dist[N], parent[N]; 4 | bool vis[N]; 5 | vector > g[N], tree[N]; 6 | 7 | int primsMST(int source) //Finds the cost and makes the MST 8 | { 9 | for(int i=1;i<=n;i++) 10 | dist[i]=1e18; 11 | set > s; 12 | s.insert({0, source}); 13 | int cost=0; 14 | dist[source]=0; 15 | while(!s.empty()) 16 | { 17 | auto x = *(s.begin()); 18 | s.erase(x); 19 | vis[x.second]=1; 20 | cost+=x.first; 21 | int u=x.second; 22 | int v=parent[x.second]; 23 | int w=x.first; 24 | tree[u].push_back({v, w}); 25 | tree[v].push_back({u, w}); 26 | for(auto it:g[x.second]) 27 | { 28 | if(vis[it.first]) 29 | continue; 30 | if(dist[it.first] > it.second) 31 | { 32 | s.erase({dist[it.first], it.first}); 33 | dist[it.first]=it.second; 34 | s.insert({dist[it.first], it.first}); 35 | parent[it.first]=x.second; 36 | } 37 | } 38 | } 39 | return cost; 40 | } 41 | 42 | //Sample Problem 1: https://codeforces.com/contest/609/problem/E 43 | //Sample Solution 1: https://codeforces.com/contest/609/submission/39951860 44 | -------------------------------------------------------------------------------- /2 Closest Points in 2D Plane (N log^2 N).cpp: -------------------------------------------------------------------------------- 1 | struct Point 2 | { 3 | int x, y; 4 | 5 | Point operator -(Point p) 6 | { 7 | return {x-p.x, y-p.y}; 8 | } 9 | 10 | int dist() 11 | { 12 | return x*x + y*y; 13 | } 14 | }; 15 | 16 | bool by_x(Point &a, Point &b) 17 | { 18 | return a.x < b.x; 19 | } 20 | 21 | bool by_y(Point &a, Point &b) 22 | { 23 | return a.y < b.y; 24 | } 25 | 26 | int n, ans=1e18; 27 | int a[N], pref[N]; 28 | Point pt[N]; 29 | 30 | int solve(int L, int R) 31 | { 32 | if(L==R) 33 | return 1e18; 34 | int M=(L+R)/2; 35 | sort(pt+L, pt+R+1, by_x); 36 | int d=min(solve(L, M), solve(M+1, R)); 37 | int midx=pt[L+(R-L+1)/2].x; 38 | vector v; 39 | for(int i=L;i<=R;i++) 40 | { 41 | if(Point{pt[i].x-midx, 0}.dist()d) 52 | break; 53 | d=min(d, (v[i]-v[j]).dist()); 54 | } 55 | } 56 | return d; 57 | } 58 | 59 | Problem 1: http://codeforces.com/contest/429/problem/D 60 | Solution 1: http://codeforces.com/contest/429/submission/39494778 61 | -------------------------------------------------------------------------------- /Geometry.cpp: -------------------------------------------------------------------------------- 1 | struct point 2 | { 3 | int x, y, idx; 4 | }; 5 | 6 | //Finds squared euclidean distance between two points 7 | int dist(point &a, point &b) 8 | { 9 | return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y); 10 | } 11 | 12 | //Checks if angle ABC is a right angle 13 | int isOrthogonal(point &a, point &b, point &c) 14 | { 15 | return (b.x-a.x) * (b.x-c.x) + (b.y-a.y) * (b.y-c.y) == 0; 16 | } 17 | 18 | //Checks if ABCD form a rectangle (in that order) 19 | int isRectangle(point &a, point &b, point &c, point &d) 20 | { 21 | return isOrthogonal(a, b, c) && isOrthogonal(b, c, d) && isOrthogonal(c, d, a); 22 | } 23 | 24 | //Checks if ABCD form a rectangle, in any orientation 25 | int isRectangleAnyOrder(point &a, point &b, point &c, point &d) 26 | { 27 | return isRectangle(a, b, c, d) || isRectangle(b, c, a, d) | isRectangle(c, a, b, d); 28 | } 29 | 30 | //Checks if ABCD form a square (in that order) 31 | int isSquare(point &a, point &b, point &c, point &d) 32 | { 33 | return isRectangle(a, b, c, d) && dist(a, b) == dist(b, c); 34 | } 35 | 36 | //Checks if ABCD form a square, in any orientation 37 | int isSquareAnyOrder(point &a, point &b, point &c, point &d) 38 | { 39 | return isSquare(a, b, c, d) || isSquare(b, c, a, d) | isSquare(c, a, b, d); 40 | } 41 | -------------------------------------------------------------------------------- /Primitive Root.cpp: -------------------------------------------------------------------------------- 1 | // g is O(log^6 n). 2 | // Run Time of algorithm is O(ans * log phi(n) * log n), which is approximately O(log^8 n). 3 | 4 | int pow(int a, int b, int m) 5 | { 6 | int ans=1; 7 | while(b) 8 | { 9 | if(b&1) 10 | ans=(1LL*ans*a)%m; 11 | b/=2; 12 | a=(1LL*a*a)%m; 13 | } 14 | return ans; 15 | } 16 | 17 | int totient(int n) 18 | { 19 | int ans=n; 20 | for(int i=2;i*i<=n;i++) 21 | { 22 | if(n%i==0) 23 | { 24 | while(n%i==0) 25 | n/=i; 26 | ans-=n/i; 27 | } 28 | } 29 | if(n>1) 30 | ans-=ans/n; 31 | return ans; 32 | } 33 | 34 | //Primitive root only exists if X=1, 4, Prime, (Odd Prime)^k, 2*(Odd Prime)^K 35 | 36 | int getPrimitive(int x) //Returns -1 if there is no primitive root 37 | { 38 | vector factors; 39 | int phi=totient(x); 40 | int n=phi; 41 | for(int i=2;i*i<=n;i++) 42 | { 43 | if(n%i==0) 44 | { 45 | factors.push_back(i); 46 | while(n%i==0) 47 | n/=i; 48 | } 49 | } 50 | if(n>1) 51 | factors.push_back(n); 52 | for(int prim=2;prim<=x;prim++) 53 | { 54 | bool check=true; 55 | for(int i=0;i=0;i--) 22 | { 23 | if((h>>i) & 1) 24 | u = parent[i][u]; 25 | } 26 | return u; 27 | } 28 | 29 | void precompute() 30 | { 31 | for(int i=1;i=0;i--) 43 | { 44 | if((1<=0;i--) 52 | { 53 | if(parent[i][u] && parent[i][u]!=parent[i][v]) 54 | { 55 | u=parent[i][u]; 56 | v=parent[i][v]; 57 | } 58 | } 59 | return parent[0][u]; 60 | } 61 | 62 | int dist(int u, int v) 63 | { 64 | return level[u] + level[v] - 2 * level[LCA(u, v)]; 65 | } 66 | 67 | //Problem 1 (Dynamic Diameter): https://codeforces.com/problemset/problem/379/F 68 | //Solution 1: https://codeforces.com/contest/379/submission/45960185 69 | -------------------------------------------------------------------------------- /Hungarian.cpp: -------------------------------------------------------------------------------- 1 | //Ref - https://codeforces.com/contest/1107/submission/49215548 2 | 3 | lli hungarian(vector> cost) // cost is 1-based 4 | { 5 | lli n = (lli)cost.size() - 1; 6 | lli m = (lli)cost[0].size() - 1; 7 | vector u(n + 1), v(m + 1), p(m + 1), way(m + 1); 8 | for (lli i = 1; i <= n; ++i) { 9 | p[0] = i; 10 | lli j0 = 0; 11 | vector minv(m + 1, INF); 12 | vector used(m + 1, false); 13 | do { 14 | used[j0] = true; 15 | lli i0 = p[j0], delta = INF, j1; 16 | for (lli j = 1; j <= m; ++j) 17 | if (!used[j]) { 18 | lli cur = cost[i0][j] - u[i0] - v[j]; 19 | if (cur < minv[j]) 20 | minv[j] = cur, way[j] = j0; 21 | if (minv[j] < delta) 22 | delta = minv[j], j1 = j; 23 | } 24 | for (lli j = 0; j <= m; ++j) 25 | if (used[j]) 26 | u[p[j]] += delta, v[j] -= delta; 27 | else 28 | minv[j] -= delta; 29 | j0 = j1; 30 | } while (p[j0] != 0); 31 | do { 32 | lli j1 = way[j0]; 33 | p[j0] = p[j1]; 34 | j0 = j1; 35 | } while (j0); 36 | } 37 | vector assignment(n + 1); 38 | for (lli j = 1; j <= m; ++j) 39 | assignment[p[j]] = j; 40 | lli ret = 0; 41 | for (lli i = 1; i <= n; ++i) 42 | { 43 | assert(assignment[i]); 44 | ret += cost[i][assignment[i]]; 45 | } 46 | 47 | return ret; 48 | } -------------------------------------------------------------------------------- /Strongly Connected Component.cpp: -------------------------------------------------------------------------------- 1 | vector g[N], newg[N], rg[N], todo; 2 | int comp[N], indeg[N]; 3 | bool vis[N]; 4 | vector gr[N]; 5 | 6 | void dfs(int k) 7 | { 8 | vis[k]=1; 9 | for(auto it:g[k]) 10 | { 11 | if(!vis[it]) 12 | dfs(it); 13 | } 14 | todo.push_back(k); 15 | } 16 | 17 | void dfs2(int k, int val) 18 | { 19 | comp[k]=val; 20 | for(auto it:rg[k]) 21 | { 22 | if(comp[it]==-1) 23 | dfs2(it, val); 24 | } 25 | } 26 | 27 | void sccAddEdge(int from, int to) 28 | { 29 | g[from].push_back(to); 30 | rg[to].push_back(from); 31 | } 32 | 33 | void scc() 34 | { 35 | for(int i=1;i<=n;i++) 36 | comp[i]=-1; 37 | 38 | for(int i=1;i<=n;i++) 39 | { 40 | if(!vis[i]) 41 | dfs(i); 42 | } 43 | 44 | reverse(todo.begin(), todo.end()); 45 | 46 | for(auto it:todo) 47 | { 48 | if(comp[it]==-1) 49 | { 50 | dfs2(it, ++grp); 51 | } 52 | } 53 | } 54 | 55 | //Sample Problem 1 (SCC Compression): http://codeforces.com/contest/999/problem/E 56 | //Sample Solution 1: http://codeforces.com/contest/999/submission/39489910 57 | 58 | //Sample Problem 2 (Detection of Directed Cycle in a connected component): http://codeforces.com/contest/505/problem/D 59 | //Sample Solution 2: http://codeforces.com/contest/505/submission/39885530 60 | 61 | //Sample Problem 3: https://codeforces.com/contest/118/problem/E 62 | //Sample Solution 3: https://codeforces.com/contest/118/submission/39888563 63 | -------------------------------------------------------------------------------- /polynomialInverse.cpp: -------------------------------------------------------------------------------- 1 | // #include 2 | // #include 3 | // using namespace atcoder; 4 | // using mint = modint998244353; 5 | 6 | // Ref - https://www.codechef.com/viewsolution/41909444 Line 850 - 886. 7 | template 8 | vector polyInverse(vector& h,int len){ 9 | auto add=[](vector a,vector b) -> vector 10 | { 11 | if(sz(a) &a,const vector &b) -> vector 18 | { 19 | return convolution(a,b); 20 | }; 21 | int n=1; 22 | while(n ans; 26 | ans.pb(h[0].pow(mod-2)); 27 | for(int l = 2;l<=n;l*=2){ 28 | vector a = ans; 29 | vector h0 = vector(h.begin(),h.begin()+l/2); 30 | vector h1 = vector(h.begin()+l/2,h.begin()+l); 31 | vector c = conv(a,h0); 32 | if(sz(c)(c.begin()+l/2,c.end()); 34 | vector tem = add(c,conv(a,h1)); 35 | tem.resize(l/2,T(0)); 36 | vector b = conv(a,tem); 37 | b.resize(l/2,T(0)); 38 | for(auto i:b) ans.pb(-i); 39 | } 40 | // while(sz(ans)>1&&ans.back()==0) ans.pop_back(); 41 | while(sz(h)>1&&h.back()==0) h.pop_back(); 42 | return ans; 43 | } -------------------------------------------------------------------------------- /FFT (Recursive).cpp: -------------------------------------------------------------------------------- 1 | const double PI = 4*atan(1); 2 | const int N=2e5+5; 3 | const int MOD=13313; 4 | 5 | int FFT_N=0; 6 | vector omega; 7 | 8 | void init_fft(int n) 9 | { 10 | FFT_N = n; 11 | omega.resize(n); 12 | double angle = 2*PI/n; 13 | for(int i=0;i &a) 20 | { 21 | int n=a.size(); 22 | if(n==1) 23 | return; 24 | int half=n>>1; 25 | vector even(half), odd(half); 26 | for(int i=0, j=0; i &a, vector &b, vector &res) 43 | { 44 | vector fa(a.begin(), a.end()); 45 | vector fb(b.begin(), b.end()); 46 | int n=1; 47 | while(n<2*max(a.size(), b.size())) 48 | n<<=1; 49 | fa.resize(n); 50 | fb.resize(n); 51 | init_fft(n); 52 | fft(fa); 53 | fft(fb); 54 | for(int i=0;i > g[N]; 14 | data edges[N]; 15 | 16 | void init() 17 | { 18 | for(int i=1;i<=n;i++) 19 | { 20 | root[i]=i; 21 | sz[i]=1; 22 | } 23 | connected=n; 24 | } 25 | 26 | int rt(int k) 27 | { 28 | while(k!=root[k]) 29 | { 30 | root[k]=root[root[k]]; 31 | k=root[k]; 32 | } 33 | return k; 34 | } 35 | 36 | void merge(int u, int v) 37 | { 38 | int rt1=rt(u); 39 | int rt2=rt(v); 40 | 41 | if(rt1==rt2) 42 | return; 43 | 44 | connected--; 45 | 46 | if(sz[rt1]>sz[rt2]) 47 | swap(rt1, rt2); 48 | 49 | sz[rt2]+=sz[rt1]; 50 | sz[rt1]=0; 51 | root[rt1]=root[rt2]; 52 | } 53 | 54 | void add_edge(int idx, int u, int v, int w) 55 | { 56 | g[u].push_back({v, w}); 57 | g[v].push_back({u, w}); 58 | edges[idx]=edge(u, v, w, idx); 59 | } 60 | 61 | bool comp(data &d1, data &d2) 62 | { 63 | return d1.w < d2.w; 64 | } 65 | 66 | int kruskalMST() 67 | { 68 | init(); 69 | int cost=0; 70 | sort(edges+1, edges+m+1, comp); 71 | for(int i=1;i<=m;i++) 72 | { 73 | int u=edges[i].u, v=edges[i].v, w=edges[i].w; 74 | int rt1=rt(u), rt2=rt(v); 75 | if(rt1==rt2) 76 | continue; 77 | else 78 | { 79 | cost+=w; 80 | merge(rt1, rt2); 81 | } 82 | } 83 | return cost; 84 | } 85 | 86 | //Problem 1 (Kruskal + Flow): https://codeforces.com/gym/101667 : Problem E 87 | //Solution 1: http://p.ip.fi/HHLC 88 | -------------------------------------------------------------------------------- /Mo's Algorithm.cpp: -------------------------------------------------------------------------------- 1 | const int N = 2e5 + 5; 2 | const int Q = 2e5 + 5; 3 | const int M = 1e6 + 5; 4 | const int SZ = sqrt(N) + 1; 5 | 6 | struct data 7 | { 8 | int l, r, idx; 9 | }qr[Q]; 10 | 11 | int n, q, a[N]; 12 | int freq[M]; 13 | long long ans[Q]; 14 | long long cur = 0; 15 | 16 | bool comp(struct data &d1, struct data &d2) 17 | { 18 | int b1 = d1.l / SZ; 19 | int b2 = d2.l / SZ; 20 | if(b1 != b2) 21 | return b1 < b2; 22 | else 23 | return (b1 & 1) ? d1.r < d2.r : d1.r > d2.r; 24 | } 25 | 26 | inline void add(int x) 27 | { 28 | cur -= 1LL * freq[x] * freq[x] * x; 29 | freq[x]++; 30 | cur += 1LL * freq[x] * freq[x] * x; 31 | } 32 | 33 | inline void remove(int x) 34 | { 35 | cur -= 1LL * freq[x] * freq[x] * x; 36 | freq[x]--; 37 | cur += 1LL * freq[x] * freq[x] * x; 38 | } 39 | 40 | void mo() 41 | { 42 | sort(qr + 1, qr + q + 1, comp); 43 | int l = 1, r = 0; 44 | cur = 0; 45 | for(int i=1;i<=q;i++) 46 | { 47 | while(l < qr[i].l) remove(a[l++]); 48 | while(l > qr[i].l) add(a[--l]); 49 | while(r < qr[i].r) add(a[++r]); 50 | while(r > qr[i].r) remove(a[r--]); 51 | ans[qr[i].idx] = cur; 52 | } 53 | } 54 | 55 | 56 | //Problem 1: https://codeforces.com/contest/86/problem/D 57 | //Solution 1: https://codeforces.com/contest/86/submission/50507192 58 | 59 | //Problem 2 (Prefix Xor): https://codeforces.com/contest/617/problem/E 60 | //Solution 2: https://codeforces.com/contest/617/submission/45491963 61 | 62 | //Problem 3 (Inversions in a Range): https://www.codechef.com/CCOQ2019/problems/DRAGONS/ 63 | //Solution 3: https://www.codechef.com/viewsolution/23234139 64 | -------------------------------------------------------------------------------- /Parallel Binary Search.cpp: -------------------------------------------------------------------------------- 1 | int lo[N], mid[N], hi[N]; 2 | vector vec[N]; 3 | 4 | void clear() //Reset 5 | { 6 | memset(bit, 0, sizeof(bit)); 7 | } 8 | 9 | void apply(int idx) //Apply ith update/query 10 | { 11 | if(ql[idx] <= qr[idx]) 12 | update(ql[idx], qa[idx]), update(qr[idx]+1, -qa[idx]); 13 | else 14 | { 15 | update(1, qa[idx]); 16 | update(qr[idx]+1, -qa[idx]); 17 | update(ql[idx], qa[idx]); 18 | } 19 | } 20 | 21 | bool check(int idx) //Check if the condition is satisfied 22 | { 23 | int req=reqd[idx]; 24 | for(auto &it:owns[idx]) 25 | { 26 | req-=pref(it); 27 | if(req<0) 28 | break; 29 | } 30 | if(req<=0) 31 | return 1; 32 | return 0; 33 | } 34 | 35 | void work() 36 | { 37 | for(int i=1;i<=q;i++) 38 | vec[i].clear(); 39 | for(int i=1;i<=n;i++) 40 | if(mid[i]>0) 41 | vec[mid[i]].push_back(i); 42 | clear(); 43 | for(int i=1;i<=q;i++) 44 | { 45 | apply(i); 46 | for(auto &it:vec[i]) //Add appropriate check conditions 47 | { 48 | if(check(it)) 49 | hi[it]=i; 50 | else 51 | lo[it]=i+1; 52 | } 53 | } 54 | } 55 | 56 | void parallel_binary() 57 | { 58 | for(int i=1;i<=n;i++) 59 | lo[i]=1, hi[i]=q+1; 60 | bool changed = 1; 61 | while(changed) 62 | { 63 | changed=0; 64 | for(int i=1;i<=n;i++) 65 | { 66 | if(lo[i] g[MAXV], rg[MAXV]; //g=forward, rg=backward 7 | bool vis[MAXV]; 8 | int order[MAXV], comp[MAXV]; 9 | 10 | void init(int curn) 11 | { 12 | n=curn; 13 | for(int i=0;i &ans) 44 | { 45 | cnt=0; 46 | memset(vis, 0, sizeof(vis)); 47 | for(int i=0;i=0;i--) 53 | { 54 | int u=order[i]; 55 | if(comp[u] == -1) 56 | dfs2(u, grp++); 57 | } 58 | 59 | for(int i=0;i comp[i^1]) ? i : (i^1); 68 | ans.push_back(choose); 69 | } 70 | 71 | return 1; 72 | } 73 | }; 74 | 75 | Sample Problem 1: https://codeforces.com/contest/228/problem/E 76 | Sample Solution 1: https://codeforces.com/contest/228/submission/39775751 77 | 78 | Sample Problem 2: http://codeforces.com/contest/776/problem/D 79 | Sample Solution 2: http://codeforces.com/contest/776/submission/39776230 80 | -------------------------------------------------------------------------------- /Bridge Tree in Graph.cpp: -------------------------------------------------------------------------------- 1 | int tim=0, grp=1; 2 | int u[N], v[N], comp[N]; 3 | bool vis[N], vis2[N], isBridge[M]; 4 | int tin[N], tout[N], minAncestor[N]; 5 | queue Q[N]; 6 | vector > g[N]; 7 | vector tree[N], vertices[N]; //Tree stores Bridge Tree, vertices stores the nodes in each component 8 | 9 | void dfs(int k, int par) 10 | { 11 | vis[k]=1; 12 | tin[k]=++tim; 13 | minAncestor[k]=tin[k]; 14 | for(auto it:g[k]) 15 | { 16 | if(it.first==par) 17 | continue; 18 | if(vis[it.first]) 19 | { 20 | minAncestor[k]=min(minAncestor[k], tin[it.first]); 21 | continue; 22 | } 23 | dfs(it.first, k); 24 | minAncestor[k]=min(minAncestor[k], minAncestor[it.first]); 25 | if(minAncestor[it.first]>tin[k]) 26 | isBridge[it.second]=1; 27 | } 28 | tout[k]=tim; 29 | } 30 | 31 | void dfs2(int k) 32 | { 33 | int comp=grp; 34 | Q[comp].push(k); 35 | vis2[k]=1; 36 | while(!Q[comp].empty()) 37 | { 38 | int u=Q[comp].front(); 39 | Q[comp].pop(); 40 | vertices[comp].push_back(u); 41 | for(auto it:g[u]) 42 | { 43 | int v=it.first; 44 | int edgeidx=it.second; 45 | if(vis2[v]) 46 | continue; 47 | if(isBridge[edgeidx]) 48 | { 49 | grp++; 50 | tree[comp].push_back(grp); 51 | tree[grp].push_back(comp); 52 | dfs2(v); 53 | } 54 | else 55 | { 56 | Q[comp].push(v); 57 | vis2[v]=1; 58 | } 59 | } 60 | } 61 | } 62 | 63 | //Problem 1: http://codeforces.com/contest/1000/problem/E 64 | //Solution 1: http://codeforces.com/contest/1000/submission/40743431 65 | 66 | //Problem 2: http://codeforces.com/contest/178/problem/B3 67 | //Solution 2: http://codeforces.com/contest/178/submission/40744889 68 | -------------------------------------------------------------------------------- /DSU (Disjoint Set Union).cpp: -------------------------------------------------------------------------------- 1 | Without Struct: 2 | 3 | int connected; 4 | int root[N], sz[N]; 5 | 6 | void init() 7 | { 8 | for(int i=1;i<=n;i++) 9 | { 10 | root[i]=i; 11 | sz[i]=1; 12 | } 13 | connected=n; 14 | } 15 | 16 | int rt(int k) 17 | { 18 | while(k!=root[k]) 19 | { 20 | root[k]=root[root[k]]; 21 | k=root[k]; 22 | } 23 | return k; 24 | } 25 | 26 | void merge(int u, int v) 27 | { 28 | int rt1=rt(u); 29 | int rt2=rt(v); 30 | 31 | if(rt1==rt2) 32 | return; 33 | 34 | connected--; 35 | 36 | if(sz[rt1]>sz[rt2]) 37 | swap(rt1, rt2); 38 | 39 | sz[rt2]+=sz[rt1]; 40 | sz[rt1]=0; 41 | root[rt1]=root[rt2]; 42 | } 43 | 44 | --- 45 | 46 | Struct Implementation: 47 | 48 | struct DSU 49 | { 50 | int connected; 51 | int par[N], sz[N]; 52 | 53 | DSU() {} 54 | 55 | DSU(int n) 56 | { 57 | for(int i=1;i<=n;i++) 58 | { 59 | par[i]=i; 60 | sz[i]=1; 61 | } 62 | connected=n; 63 | } 64 | 65 | int getPar(int k) 66 | { 67 | while(k!=par[k]) 68 | { 69 | par[k]=par[par[k]]; 70 | k=par[k]; 71 | } 72 | return k; 73 | } 74 | 75 | int getSize(int k) 76 | { 77 | return sz[getPar(k)]; 78 | } 79 | 80 | void unite(int u, int v) 81 | { 82 | int par1=getPar(u), par2=getPar(v); 83 | 84 | if(par1==par2) 85 | return; 86 | 87 | connected--; 88 | 89 | if(sz[par1]>sz[par2]) 90 | swap(par1, par2); 91 | 92 | sz[par2]+=sz[par1]; 93 | sz[par1]=0; 94 | par[par1]=par[par2]; 95 | } 96 | }; 97 | 98 | //Problem 1 (DSU + Divide and Conquer): https://codeforces.com/contest/813/problem/F 99 | //Solution 1: https://codeforces.com/contest/813/submission/48548930 100 | -------------------------------------------------------------------------------- /KMP.cpp: -------------------------------------------------------------------------------- 1 | String: 2 | 3 | vector prefix_function(string &s) 4 | { 5 | int n = (int)s.length(); 6 | vector pi(n); 7 | for (int i = 1; i < n; i++) 8 | { 9 | int j = pi[i-1]; 10 | while (j > 0 && s[i] != s[j]) 11 | j = pi[j-1]; 12 | if (s[i] == s[j]) 13 | j++; 14 | pi[i] = j; 15 | } 16 | return pi; 17 | } 18 | 19 | vector find_occurences(string &text, string &pattern) 20 | { 21 | string cur=pattern + '#' + text; 22 | int sz1=text.size(), sz2=pattern.size(); 23 | vector v; 24 | vector lps=prefix_function(cur); 25 | for(int i=sz2+1;i<=sz1+sz2;i++) 26 | { 27 | if(lps[i]==sz2) 28 | v.push_back(i-2*sz2); 29 | } 30 | return v; 31 | } 32 | 33 | Vector: 34 | 35 | vector prefix_function(vector &v) 36 | { 37 | int n = (int)v.size(); 38 | vector pi(n); 39 | for (int i = 1; i < n; i++) 40 | { 41 | int j = pi[i-1]; 42 | while (j > 0 && v[i] != v[j]) 43 | j = pi[j-1]; 44 | if (v[i] == v[j]) 45 | j++; 46 | pi[i] = j; 47 | } 48 | return pi; 49 | } 50 | 51 | vector find_occurences(vector &text, vector &pattern) 52 | { 53 | vector v=pattern; 54 | v.push_back(-1); 55 | for(auto &it:text) 56 | v.push_back(it); 57 | int sz1=text.size(), sz2=pattern.size(); 58 | vector lps=prefix_function(v); 59 | vector store; 60 | for(int i=sz2+1;i<=sz1+sz2;i++) 61 | { 62 | if(lps[i]==sz2) 63 | store.push_back(i-sz*2); 64 | } 65 | return v; 66 | } 67 | 68 | 69 | //Problem 1 (Basic KMP): https://codeforces.com/contest/1016/problem/B 70 | //Solution 1: https://codeforces.com/contest/1016/submission/41167402 71 | 72 | //Problem 2 and Solution (Cyclic Matching - Vectors): http://codeforces.com/gym/100502/submission/41562571 73 | 74 | //Problem 3 (Ranking Pattern): https://qr.ae/TUG5h9 75 | //Solution 3: http://p.ip.fi/Hwpy 76 | -------------------------------------------------------------------------------- /Matching (Hopcroft-Karp) in Bipartite Graph.cpp: -------------------------------------------------------------------------------- 1 | //1 indexed Hopcroft-Karp Matching in O(E sqrtV) 2 | 3 | struct Hopcroft_Karp 4 | { 5 | static const int inf = 1e9; 6 | 7 | int n; 8 | vector matchL, matchR, dist; 9 | vector > g; 10 | 11 | Hopcroft_Karp(int n) : 12 | n(n), matchL(n+1), matchR(n+1), dist(n+1), g(n+1) {} 13 | 14 | void addEdge(int u, int v) 15 | { 16 | g[u].push_back(v); 17 | } 18 | 19 | bool bfs() 20 | { 21 | queue q; 22 | for(int u=1;u<=n;u++) 23 | { 24 | if(!matchL[u]) 25 | { 26 | dist[u]=0; 27 | q.push(u); 28 | } 29 | else 30 | dist[u]=inf; 31 | } 32 | dist[0]=inf; 33 | 34 | while(!q.empty()) 35 | { 36 | int u=q.front(); 37 | q.pop(); 38 | for(auto v:g[u]) 39 | { 40 | if(dist[matchR[v]] == inf) 41 | { 42 | dist[matchR[v]] = dist[u] + 1; 43 | q.push(matchR[v]); 44 | } 45 | } 46 | } 47 | 48 | return (dist[0]!=inf); 49 | } 50 | 51 | bool dfs(int u) 52 | { 53 | if(!u) 54 | return true; 55 | for(auto v:g[u]) 56 | { 57 | if(dist[matchR[v]] == dist[u]+1 &&dfs(matchR[v])) 58 | { 59 | matchL[u]=v; 60 | matchR[v]=u; 61 | return true; 62 | } 63 | } 64 | dist[u]=inf; 65 | return false; 66 | } 67 | 68 | int max_matching() 69 | { 70 | int matching=0; 71 | while(bfs()) 72 | { 73 | for(int u=1;u<=n;u++) 74 | { 75 | if(!matchL[u]) 76 | if(dfs(u)) 77 | matching++; 78 | } 79 | } 80 | return matching; 81 | } 82 | }; 83 | 84 | //Problem 1: https://codeforces.com/contest/387/problem/D 85 | //Solution 1: https://codeforces.com/contest/387/submission/48378847 86 | 87 | //Problem 2 (Ensuring that matching is consistent): https://www.spoj.com/problems/ADABLOOM/ 88 | //Solution 2:http://p.ip.fi/igSb 89 | 90 | //Problem 3: https://codeforces.com/gym/101853/problem/B 91 | -------------------------------------------------------------------------------- /Persistent Segment Tree.cpp: -------------------------------------------------------------------------------- 1 | int n, m, ct=0, num=0; 2 | int root[N], st[21*N], lc[21*N], rc[21*N]; 3 | 4 | int build(int L, int R) 5 | { 6 | int node = ++ct; 7 | if(L==R) 8 | return node; 9 | int M = (L+R)/2; 10 | lc[node] = build(L, M); 11 | rc[node] = build(M+1, R); 12 | return node; 13 | } 14 | 15 | int update(int onode, int L, int R, int pos) 16 | { 17 | int node = ++ct; 18 | if(L==R) 19 | { 20 | st[node] = st[onode] + 1; 21 | return node; 22 | } 23 | int M = (L+R)/2; 24 | lc[node] = lc[onode]; 25 | rc[node] = rc[onode]; 26 | if(pos <= M) 27 | lc[node] = update(lc[onode], L, M, pos); 28 | else 29 | rc[node] = update(rc[onode], M+1, R, pos); 30 | st[node] = st[lc[node]] + st[rc[node]]; 31 | return node; 32 | } 33 | 34 | int query(int nodeu, int nodev, int L, int R, int pos) 35 | { 36 | if(L==R) 37 | return L; 38 | int M = (L+R)/2; 39 | int leftval = st[lc[nodev]] - st[lc[nodeu]]; 40 | int rightval = st[rc[nodev]] - st[rc[nodeu]]; 41 | if(leftval>=pos) 42 | return query(lc[nodeu], lc[nodev], L, M, pos); 43 | else 44 | return query(rc[nodeu], rc[nodev], M+1, R, pos - leftval); 45 | } 46 | 47 | void persistentSegTree() 48 | { 49 | root[0] = build(1, num); 50 | for(int i=1;i<=n;i++) 51 | root[i] = update(root[i-1], 1, num, a[i]); 52 | } 53 | 54 | //Problem 1 (kth minimum weight on the path from node u to node v): https://www.spoj.com/problems/COT/ 55 | //Solution 1: http://p.ip.fi/KLiG 56 | 57 | //Problem 2 (Kth element in sorted range [i, j]): https://www.spoj.com/problems/MKTHNUM/ 58 | //Solution 2: http://p.ip.fi/B00r 59 | 60 | //Problem 3 (Take atmost K values of a particular value in a range): https://codeforces.com/contest/813/problem/E 61 | //Solution 3: https://codeforces.com/contest/813/submission/50422337 62 | 63 | //Problem 4: https://www.codechef.com/ICMT2019/problems/ICM05 64 | //Solution 4: http://p.ip.fi/bo0f 65 | -------------------------------------------------------------------------------- /Extended Euclidean Algorithm (Extensive).cpp: -------------------------------------------------------------------------------- 1 | int xgcd(int a, int b, int &x, int &y) //Returns GCD of A, B 2 | { 3 | if(a==0) 4 | { 5 | x=0; 6 | y=1; 7 | return b; 8 | } 9 | int x1, y1; 10 | int d = xgcd(b % a, a, x1, y1); 11 | x = y1 - (b/a)*x1; 12 | y = x1; 13 | return d; 14 | } 15 | 16 | int modular_inverse(int a, int m) 17 | { 18 | int x, y; 19 | int g=xgcd(a, m, x, y); 20 | if(g!=1) 21 | return -1; 22 | else 23 | { 24 | x=(x%m + m)%m; 25 | return x; 26 | } 27 | } 28 | 29 | void shift_solution(int &x, int &y, int a, int b, int cnt) 30 | { 31 | x+=cnt*b; 32 | y-=cnt*a; 33 | } 34 | 35 | bool find_any_solution(int a, int b, int c, int &x0, int &y0) 36 | { 37 | int g=xgcd(abs(a), abs(b), x0, y0); 38 | if(c%g!=0) 39 | return false; 40 | x0 *= c/g; 41 | y0 *= c/g; 42 | if(a<0) 43 | x0*=-1; 44 | if(b<0) 45 | y0*=-1; 46 | return true; 47 | } 48 | 49 | int find_all_solutions(int a, int b, int c, int minx, int maxx, int miny, int maxy) //Returns number of solutions with x∈[minx, maxx], y∈[miny, maxy] 50 | { 51 | int x, y, g; 52 | if(!find_any_solution(a, b, c, x, y, g)) 53 | return 0; 54 | a /= g; 55 | b /= g; 56 | 57 | int sign_a = a>0 ? +1 : -1; 58 | int sign_b = b>0 ? +1 : -1; 59 | 60 | shift_solution(x, y, a, b, (minx - x) / b); 61 | if (x < minx) shift_solution(x, y, a, b, sign_b); 62 | if (x > maxx) return 0; 63 | int lx1 = x; 64 | 65 | shift_solution(x, y, a, b, (maxx - x) / b); 66 | if (x > maxx) shift_solution(x, y, a, b, -sign_b); 67 | int rx1 = x; 68 | 69 | shift_solution(x, y, a, b, - (miny - y) / a); 70 | if (y < miny) shift_solution(x, y, a, b, -sign_a); 71 | if (y > maxy) return 0; 72 | int lx2 = x; 73 | 74 | shift_solution(x, y, a, b, - (maxy - y) / a); 75 | if (y > maxy) shift_solution(x, y, a, b, sign_a); 76 | int rx2 = x; 77 | 78 | if (lx2 > rx2) 79 | swap (lx2, rx2); 80 | int lx = max (lx1, lx2); 81 | int rx = min (rx1, rx2); 82 | 83 | return (rx - lx) / abs(b) + 1; 84 | } 85 | -------------------------------------------------------------------------------- /Trie.cpp: -------------------------------------------------------------------------------- 1 | typedef struct data 2 | { 3 | data* bit[2]; 4 | int cnt = 0; 5 | }trie; 6 | 7 | trie* head; 8 | 9 | void insert(int x) 10 | { 11 | trie* cur = head; 12 | for(int i=30;i>=0;i--) 13 | { 14 | int b = (x>>i) & 1; 15 | if(!cur->bit[b]) 16 | cur->bit[b] = new trie(); 17 | cur = cur->bit[b]; 18 | cur->cnt++; 19 | } 20 | } 21 | 22 | void remove(int x) 23 | { 24 | trie* cur = head; 25 | for(int i=30;i>=0;i--) 26 | { 27 | int b = (x>>i) & 1; 28 | cur = cur->bit[b]; 29 | cur->cnt--; 30 | } 31 | } 32 | 33 | int maxxor(int x) 34 | { 35 | trie* cur = head; 36 | int ans = 0; 37 | for(int i=30;i>=0;i--) 38 | { 39 | int b = (x>>i)&1; 40 | if(cur->bit[!b] && cur->bit[!b]->cnt>0) 41 | { 42 | ans += (1LL<bit[!b]; 44 | } 45 | else 46 | cur = cur->bit[b]; 47 | } 48 | return ans; 49 | } 50 | 51 | //Problem 1: http://codeforces.com/contest/706/problem/D 52 | //Solution 1: http://codeforces.com/contest/706/submission/39515647 (Maxxor) 53 | 54 | //Problem 2: http://codeforces.com/problemset/problem/948/D 55 | //Solution 2: http://codeforces.com/contest/948/submission/39663985 (Minxor) 56 | 57 | //Problem 3: http://codeforces.com/contest/665/problem/E 58 | //Solution 3: http://codeforces.com/contest/665/submission/39664021 (Subarray Count with Xor >= K) 59 | 60 | //Problem 4: http://codeforces.com/contest/282/problem/E 61 | //Solution 4: http://codeforces.com/contest/282/submission/39664030 (Maxxor) 62 | 63 | //Problem 5: https://codeforces.com/contest/842/problem/D 64 | //Solution 5: https://codeforces.com/contest/842/submission/50659739 (Recursive Insert + Mex) 65 | 66 | //Problem 6: https://www.codechef.com/problems/GPD 67 | //Solution 6: http://p.ip.fi/rz9f (Persistent Trie + Recursive Insert, MinXor, MaxXor) 68 | 69 | //Problem 7: https://www.codechef.com/problems/XRQRS 70 | //Solution 7: http://p.ip.fi/i8dl (Persistent Trie + Recursive Insert, MinXor, MaxXor, Kth Largest in interval, <=X in interval) 71 | -------------------------------------------------------------------------------- /Tree Construction with Specific Vertices.cpp: -------------------------------------------------------------------------------- 1 | int tim=0; 2 | int parent[LG][N]; 3 | int tin[N], tout[N], level[N], vertices[N]; 4 | vector g[N], tree[N]; 5 | 6 | void dfs(int k, int par, int lvl) 7 | { 8 | tin[k]=++tim; 9 | parent[0][k]=par; 10 | level[k]=lvl; 11 | for(auto it:g[k]) 12 | { 13 | if(it==par) 14 | continue; 15 | dfs(it, k, lvl+1); 16 | } 17 | tout[k]=tim; 18 | } 19 | 20 | void precompute() 21 | { 22 | for(int i=1;i=0;i--) 34 | { 35 | if((1<=0;i--) 43 | { 44 | if(parent[i][u] && parent[i][u]!=parent[i][v]) 45 | { 46 | u=parent[i][u]; 47 | v=parent[i][v]; 48 | } 49 | } 50 | return parent[0][u]; 51 | } 52 | 53 | bool isancestor(int u, int v) //Check if u is an ancestor of v 54 | { 55 | return (tin[u]<=tin[v]) && (tout[v]<=tout[u]); 56 | } 57 | 58 | int work() 59 | { 60 | sort(vertices+1, vertices+k+1, [](int a, int b) 61 | { 62 | return tin[a] s; 74 | s.push(vertices[1]); 75 | for(int i=2;i<=k;i++) 76 | { 77 | while(!isancestor(s.top(), vertices[i])) 78 | s.pop(); 79 | tree[s.top()].push_back(vertices[i]); 80 | s.push(vertices[i]); 81 | } 82 | for(int i=1;i<=k;i++) 83 | tree[vertices[i]].clear(); 84 | } 85 | 86 | //Problem 1: http://codeforces.com/contest/613/problem/D 87 | //Solution 1: http://codeforces.com/contest/613/submission/40474762 88 | 89 | -------------------------------------------------------------------------------- /DSU On Trees.cpp: -------------------------------------------------------------------------------- 1 | //Logic: https://codeforces.com/blog/entry/44351 2 | 3 | int col[N], cnt[N], f[N], subtree[N], big[N], ans[N]; 4 | vector g[N]; 5 | multiset active; 6 | 7 | void getsz(int v, int p) 8 | { 9 | subtree[v]=1; 10 | for(auto u:g[v]) 11 | { 12 | if(u==p) 13 | continue; 14 | getsz(u, v); 15 | subtree[v]+=subtree[u]; 16 | } 17 | } 18 | 19 | void add(int v, int p, int x) //Function changes as per question, 20 | { 21 | active.erase(cnt[col[v]]); 22 | f[cnt[col[v]]]-=col[v]; 23 | cnt[col[v]]+=x; 24 | active.insert(cnt[col[v]]); 25 | f[cnt[col[v]]]+=col[v]; 26 | for(auto u:g[v]) 27 | { 28 | if(u!=p && !big[u]) 29 | add(u, v, x); 30 | } 31 | } 32 | 33 | void computeans(int v) 34 | { 35 | int maxf=*(--active.end()); 36 | ans[v]=f[maxf]; 37 | } 38 | 39 | void dfs(int v, int p, int keep) 40 | { 41 | int mx = -1, bigChild = -1; 42 | for(auto u:g[v]) 43 | { 44 | if(u!=p && subtree[u]>mx) 45 | mx=subtree[u], bigChild=u; 46 | } 47 | for(auto u:g[v]) 48 | { 49 | if(u!=p && u!=bigChild) 50 | dfs(u, v, 0); //Run DFS on small children and clear them 51 | } 52 | if(bigChild!=-1) 53 | { 54 | dfs(bigChild, v, 1); 55 | big[bigChild]=1; 56 | } 57 | add(v, p, 1); 58 | //Now we have the information of subtree of v 59 | computeans(v); 60 | if(bigChild!=-1) 61 | big[bigChild]=0; 62 | if(keep==0) 63 | add(v, p, -1); 64 | } 65 | 66 | //Sample Problem 1: https://codeforces.com/contest/600/problem/E 67 | //Sample Solution 1: https://codeforces.com/contest/600/submission/40033997 68 | 69 | //Sample Problem 2: https://codeforces.com/contest/570/problem/D 70 | //Sample Solution 2 (Offline Processing): https://codeforces.com/contest/570/submission/40034531 71 | 72 | //Sample Problem 3: https://codeforces.com/problemset/problem/246/E 73 | //Sample Solution 3: https://codeforces.com/contest/246/submission/40040432 74 | 75 | //Sample Problem 4: https://codeforces.com/contest/375/problem/D 76 | //Sasmple Solution 4: https://codeforces.com/contest/375/submission/40044165 77 | -------------------------------------------------------------------------------- /Matrix Struct.cpp: -------------------------------------------------------------------------------- 1 | int add(int a, int b) 2 | { 3 | int res = a + b; 4 | if(res >= MOD) 5 | return res - MOD; 6 | return res; 7 | } 8 | 9 | int mult(int a, int b) 10 | { 11 | long long res = a; 12 | res *= b; 13 | if(res >= MOD) 14 | return res % MOD; 15 | return res; 16 | } 17 | 18 | struct matrix 19 | { 20 | int arr[SZ][SZ]; 21 | matrix() 22 | { 23 | reset(); 24 | } 25 | 26 | void reset() 27 | { 28 | memset(arr, 0, sizeof(arr)); 29 | } 30 | 31 | void makeiden() 32 | { 33 | reset(); 34 | for(int i=0;i>= 1; 83 | } 84 | return res; 85 | } 86 | 87 | //Matrix Exponentiation: 88 | //Sample Problem 1: http://codeforces.com/contest/954/problem/F 89 | //Sample Solution 1: http://codeforces.com/contest/954/submission/39865763 90 | 91 | //Sample Problem 2: http://codeforces.com/contest/821/problem/E 92 | //Sample Solution 2: http://codeforces.com/contest/821/submission/39865878 93 | 94 | //Sample Problem 3 (Only Matrix Expo): https://codeforces.com/contest/551/problem/D 95 | //Sample Solution 3: https://codeforces.com/contest/551/submission/48459284 96 | 97 | //Sample Problem 4: https://www.codechef.com/ENFE2019/problems/CHWLD 98 | //Sample Solution 4: https://www.codechef.com/viewsolution/23218422 99 | -------------------------------------------------------------------------------- /Negative Cycles in Directed Graph.cpp: -------------------------------------------------------------------------------- 1 | SPFA: 2 | 3 | int n, m; 4 | int dist[N], cnt[N]; 5 | bool inqueue[N]; 6 | vector > g[N]; 7 | 8 | bool negativeCycle() //Returns true if there is a negative cycle 9 | { 10 | queue q; 11 | 12 | for(int i=1;i<=n;i++) 13 | { 14 | dist[i]=cnt[i]=0; 15 | q.push(i), inqueue[i]=true; 16 | } 17 | 18 | while(!q.empty()) 19 | { 20 | int v=q.front(); 21 | q.pop(); 22 | inqueue[v]=false; 23 | 24 | for(auto &edge:g[v]) 25 | { 26 | int to=edge.first; 27 | int w=edge.second; 28 | 29 | if(dist[v] + w < dist[to]) 30 | { 31 | dist[to] = dist[v] + w; 32 | dist[to] = max(dist[to], INF); 33 | if(!inqueue[to]) 34 | { 35 | q.push(to); 36 | inqueue[to]=true; 37 | cnt[to]++; 38 | if(cnt[to]>n) 39 | return true; 40 | } 41 | } 42 | } 43 | } 44 | return false; 45 | } 46 | ----------------------------------------------------------------------------------------------------------------------------------------- 47 | Bellman Ford (with Path Printing of the negative cycle): 48 | 49 | const int INF=1e9; 50 | 51 | struct Edge 52 | { 53 | int u, v, cost; 54 | }; 55 | 56 | int n, m; 57 | vector edges; 58 | 59 | bool negativeCycle() //Return true if there is a negative cycle in the graph 60 | { 61 | vector dist(n+1, 0); 62 | vector par(n, -1); 63 | int x; 64 | for(int i=1;i<=n;i++) 65 | { 66 | x=-1; 67 | for(auto &e:edges) 68 | { 69 | if(dist[e.u] + e.cost < dist[e.v]) 70 | { 71 | dist[e.v] = dist[e.u] + e.cost; 72 | par[e.v] = e.u; 73 | x = e.v; 74 | } 75 | } 76 | } 77 | 78 | if(x==-1) 79 | return 0; 80 | else 81 | { 82 | for(int i=1;i<=n;i++) 83 | x=par[x]; 84 | vector cycle; 85 | for(int v=x;;v=par[v]) 86 | { 87 | cycle.push_back(v); 88 | if(v==x && cycle.size()>1) 89 | break; 90 | } 91 | reverse(cycle.begin(), cycle.end()); 92 | cout<<"Negative cycle: "; 93 | for(auto &it:cycle) 94 | cout< va, vb; 38 | int lca = -1; 39 | while(lca == -1) 40 | { 41 | if(u != -1) 42 | { 43 | u = getBCC(u); 44 | va.push_back(u); 45 | if(vis[u] == current) 46 | lca = u; 47 | vis[u] = current; 48 | u = link[u]; 49 | } 50 | if(v != -1) 51 | { 52 | vb.push_back(v); 53 | v = getBCC(v); 54 | if(vis[v] == current) 55 | lca = v; 56 | vis[v] = current; 57 | v = link[v]; 58 | } 59 | } 60 | for(auto &it:va) 61 | { 62 | bcc[it] = lca; 63 | if(it == lca) 64 | break; 65 | bridges--; 66 | } 67 | for(auto &it:vb) 68 | { 69 | bcc[it] = lca; 70 | if(it == lca) 71 | break; 72 | bridges--; 73 | } 74 | } 75 | 76 | void MakeRoot(int u) 77 | { 78 | u = getBCC(u); 79 | int root = u, child = -1; 80 | while(u != -1) 81 | { 82 | int par = getBCC(link[u]); 83 | link[u] = child; 84 | comp[u] = root; 85 | child = u; 86 | u = par; 87 | } 88 | sz[root] = sz[child]; 89 | } 90 | 91 | void addEdge(int u, int v) 92 | { 93 | u = getBCC(u), v = getBCC(v); 94 | if(u == v) 95 | return; 96 | int compu = getComp(u), compv = getComp(v); 97 | if(compu != compv) 98 | { 99 | bridges++; 100 | if(sz[compu] > sz[compv]) 101 | { 102 | swap(u, v); 103 | swap(compu, compv); 104 | } 105 | MakeRoot(u); 106 | link[u] = v; 107 | comp[u] = v; 108 | sz[compv] += sz[compu]; 109 | } 110 | else 111 | mergePath(u, v); 112 | } 113 | 114 | //Problem 1: https://www.codechef.com/ENFE2019/problems/HTST9 115 | //Solution 1: https://www.codechef.com/viewsolution/23221102 116 | -------------------------------------------------------------------------------- /Convex Hull (Graham's Scan).cpp: -------------------------------------------------------------------------------- 1 | struct point //Replace double with int if not required 2 | { 3 | double x, y; 4 | 5 | point () {} 6 | 7 | point(int x, int y) : x(x), y(y) {} 8 | 9 | void operator =(const point &p) 10 | { 11 | x=p.x, y=p.y; 12 | } 13 | 14 | bool operator <(const point&p) 15 | { 16 | if(x==p.x) 17 | return y0; 67 | } 68 | 69 | vector convex_hull(vector &v) 70 | { 71 | if(v.size()==1) 72 | return v; 73 | 74 | sort(v.begin(), v.end(), comp); 75 | 76 | point p1=v[0], p2=v.back(); 77 | 78 | vector up, down; 79 | up.push_back(p1); 80 | down.push_back(p1); 81 | 82 | for(int i=1;i=2 && !cw(up[up.size()-2], up[up.size()-1], v[i])) 87 | up.pop_back(); 88 | up.push_back(v[i]); 89 | } 90 | if(i==v.size()-1 || ccw(p1, v[i], p2)) 91 | { 92 | while(down.size()>=2 && !ccw(down[down.size()-2], down[down.size()-1], v[i])) 93 | down.pop_back(); 94 | down.push_back(v[i]); 95 | } 96 | } 97 | 98 | for(int i=down.size()-2;i>0;i--) 99 | up.push_back(down[i]); 100 | 101 | return up; 102 | } 103 | 104 | //Problem 1 (Polygon Congruence): http://codeforces.com/contest/1017/problem/E 105 | //Solution 1: http://codeforces.com/contest/1017/submission/41401690 106 | 107 | //Problem 2 and Solution: http://codeforces.com/gym/101606/submission/41541222 108 | -------------------------------------------------------------------------------- /BIT - Binary Indexed Tree (Fenwick Tree).cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct bit{ 3 | // Ref - https://codeforces.com/contest/1208/submission/59476716 4 | lli n; 5 | vector fen; 6 | bit(): n(0) {} 7 | bit(lli _n) : n(_n), fen(_n+10) {} 8 | void add(lli p,T val){ 9 | for(;p <= n;p += p & -p) 10 | fen[p] += val; 11 | } 12 | T sum(lli p){ 13 | T ans = 0; 14 | for(;p > 0;p -= p & -p) 15 | ans += fen[p]; 16 | return ans; 17 | } 18 | }; 19 | 20 | 21 | 1D BIT: 22 | 23 | lli bit[N]; 24 | 25 | void update(lli idx, lli val) 26 | { 27 | while(idx<=n) 28 | { 29 | bit[idx]+=val; 30 | idx+=idx&-idx; 31 | } 32 | } 33 | 34 | lli pref(lli idx) 35 | { 36 | lli ans=0; 37 | while(idx>0) 38 | { 39 | ans+=bit[idx]; 40 | idx-=idx&-idx; 41 | } 42 | return ans; 43 | } 44 | 45 | lli rsum(lli l, lli r) 46 | { 47 | return pref(r) - pref(l-1); 48 | } 49 | 50 | ---------------------------------------------------------------------------------------------------------------------- 51 | 52 | struct BIT 53 | { 54 | lli N; 55 | vector bit; 56 | 57 | void init(lli n) 58 | { 59 | N = n; 60 | bit.assign(n + 1, 0); 61 | } 62 | 63 | void update(lli idx, lli val) 64 | { 65 | while(idx <= N) 66 | { 67 | bit[idx] += val; 68 | idx += idx & -idx; 69 | } 70 | } 71 | 72 | void updateMax(lli idx, lli val) 73 | { 74 | while(idx <= N) 75 | { 76 | bit[idx] = max(bit[idx], val); 77 | idx += idx & -idx; 78 | } 79 | } 80 | 81 | lli pref(lli idx) 82 | { 83 | lli ans = 0; 84 | while(idx > 0) 85 | { 86 | ans += bit[idx]; 87 | idx -= idx & -idx; 88 | } 89 | return ans; 90 | } 91 | 92 | lli rsum(lli l, lli r) 93 | { 94 | return pref(r) - pref(l - 1); 95 | } 96 | 97 | lli prefMax(lli idx) 98 | { 99 | lli ans = -2e9; 100 | while(idx > 0) 101 | { 102 | ans = max(ans, bit[idx]); 103 | idx -= idx & -idx; 104 | } 105 | return ans; 106 | } 107 | }; 108 | 109 | Multiple BIT: 110 | 111 | lli bit[2][N]; 112 | 113 | void update(lli i, lli idx, lli k) 114 | { 115 | while(idx<=n) 116 | { 117 | bit[i][idx]+=k; 118 | idx+=idx&-idx; 119 | } 120 | } 121 | 122 | lli pref(lli i, lli idx) 123 | { 124 | lli ans=0; 125 | while(idx>0) 126 | { 127 | ans+=bit[i][idx]; 128 | idx-=idx&-idx; 129 | } 130 | return ans; 131 | } 132 | 133 | lli rsum(lli i, lli l, lli r) 134 | { 135 | return pref(i, r) - pref(i, l-1); 136 | } 137 | 138 | //Problem 1: https://codeforces.com/contest/1073/problem/D 139 | //Solution 1: https://codeforces.com/contest/1073/submission/44863255 140 | 141 | //Problem 2: https://www.hackerrank.com/contests/university-codesprint-4/challenges/unique-art/problem 142 | //Solution 2: http://p.ip.fi/T9YM 143 | -------------------------------------------------------------------------------- /NTT (Recursive).cpp: -------------------------------------------------------------------------------- 1 | namespace ntt{ 2 | #define re(i, n) for(lli i = 0; i < (n); ++i) 3 | #define reA(i, a, n) for(lli i = a; i <= (n); ++i) 4 | #define reD(i, a, n) for(lli i = a; i >= (n); --i) 5 | #define SZZ(x) (lli)(x).size() 6 | 7 | const lli MAGIC = 200; // (factor 10 optimization for |a|,|b| = 10) 8 | 9 | const lli mod = (119LL << 23) + 1, root = 3; // = 998244353 10 | // For p < 2^30 there is also e.g. (5 << 25, 3), (7 << 26, 3), 11 | // (479 << 21, 3) and (483 << 21, 5). The last two are > 10^9. 12 | // Credits - https://www.codechef.com/viewsolution/20497234 13 | lli modpow(lli a, lli e) { 14 | if (e == 0) return 1; 15 | lli x = modpow(a * a % mod, e >> 1); 16 | return e & 1 ? x * a % mod : x; 17 | } 18 | 19 | typedef vector vl; 20 | void ntt(lli* x, lli* temp, lli* roots, lli N, lli skip) { 21 | if (N == 1) return; 22 | lli n2 = N/2; 23 | ntt(x , temp, roots, n2, skip*2); 24 | ntt(x+skip, temp, roots, n2, skip*2); 25 | re(i,N) temp[i] = x[i*skip]; 26 | re(i,n2) { 27 | lli s = temp[2*i], t = temp[2*i+1] * roots[skip*i]; 28 | x[skip*i] = (s + t) % mod; x[skip*(i+n2)] = (s - t) % mod; 29 | } 30 | } 31 | void ntt(vl& x, bool inv = false) { 32 | lli e = modpow(root, (mod-1) / SZZ(x)); 33 | if (inv) e = modpow(e, mod-2); 34 | vl roots(SZZ(x), 1), temp = roots; 35 | reA(i,1,SZZ(x)-1) roots[i] = roots[i-1] * e % mod; 36 | ntt(&x[0], &temp[0], &roots[0], SZZ(x), 1); 37 | } 38 | 39 | void conv(vl &c,vl a, vl b) { 40 | lli s = SZZ(a) + SZZ(b) - 1; if (s <= 0) { c.clear(); return ;} 41 | lli L = s > 1 ? 32 - __builtin_clz(s - 1) : 0, n = 1 << L; 42 | 43 | if (s <= MAGIC) { // (factor 10 optimization for |a|,|b| = 10) 44 | c.clear();c.resize(s,0); 45 | re(i,SZZ(a)) re(j,SZZ(b)) 46 | c[i + j] = (c[i + j] + a[i] * b[j]) % mod; 47 | return; 48 | } 49 | 50 | a.resize(n,0); ntt(a); 51 | b.resize(n,0); ntt(b); 52 | c.clear();c.resize(n,0); 53 | lli d = modpow(n, mod-2); 54 | re(i,n) c[i] = a[i] * b[i] % mod * d % mod; 55 | ntt(c, true); c.resize(s); 56 | for(auto &x:c) 57 | { 58 | if(x<0) 59 | x+=mod; 60 | } 61 | } 62 | 63 | // a*a 64 | void conv2(vl &c,vl a) { 65 | lli s = 2*SZZ(a) - 1; if (s <= 0) { c.clear(); return ;} 66 | lli L = s > 1 ? 32 - __builtin_clz(s - 1) : 0, n = 1 << L; 67 | 68 | if (s <= MAGIC) { // (factor 10 optimization for |a|,|b| = 10) 69 | c.clear();c.resize(s,0); 70 | re(i,SZZ(a)) re(j,SZZ(a)) 71 | c[i + j] = (c[i + j] + a[i] * a[j]) % mod; 72 | return; 73 | } 74 | 75 | a.resize(n,0); ntt(a); 76 | c.clear();c.resize(n,0); 77 | lli d = modpow(n, mod-2); 78 | re(i,n) c[i] = a[i] * a[i] % mod * d % mod; 79 | ntt(c, true); c.resize(s); 80 | for(auto &x:c) 81 | { 82 | if(x<0) 83 | x+=mod; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | Dijkstra with Path: 2 | 3 | int arrival[N], departure[N], vis[N], parent[N]; 4 | vector > g[N]; 5 | 6 | void dijkstra(int source, int destination) 7 | { 8 | for(int i=1;i<=n;i++) 9 | { 10 | arrival[i]=1e18; 11 | departure[i]=1e18; 12 | vis[i]=0; 13 | } 14 | arrival[source]=0; 15 | set > s; 16 | s.insert({0, source}); 17 | while(!s.empty()) 18 | { 19 | auto x = *(s.begin()); 20 | s.erase(x); 21 | vis[x.second]=1; 22 | departure[x.second]=arrival[x.second]; 23 | for(auto it:g[x.second]) 24 | { 25 | if(arrival[it.first] > departure[x.second] + it.second) 26 | { 27 | s.erase({arrival[it.first], it.first}); 28 | arrival[it.first]=departure[x.second] + it.second; 29 | s.insert({arrival[it.first], it.first}); 30 | parent[it.first]=x.second; 31 | } 32 | } 33 | } 34 | if(!vis[destination]) 35 | { 36 | cout<<"-1"; 37 | return; 38 | } 39 | int v=destination; 40 | vector ans; 41 | while(parent[v]) 42 | { 43 | ans.push_back(v); 44 | v=parent[v]; 45 | } 46 | ans.push_back(source); 47 | reverse(ans.begin(), ans.end()); 48 | for(auto it:ans) 49 | cout< > g[N]; 57 | 58 | void dijkstra(int source, int destination, int arrival[], int departure[]) 59 | { 60 | for(int i=1;i<=n;i++) 61 | { 62 | arrival[i]=inf; 63 | departure[i]=inf; 64 | } 65 | arrival[source]=0; 66 | set > s; 67 | s.insert({0, source}); 68 | while(!s.empty()) 69 | { 70 | auto x = *(s.begin()); 71 | s.erase(x); 72 | departure[x.second]=arrival[x.second]; 73 | for(auto it:g[x.second]) 74 | { 75 | if(arrival[it.first] > departure[x.second] + it.second) 76 | { 77 | s.erase({arrival[it.first], it.first}); 78 | arrival[it.first]=departure[x.second] + it.second; 79 | s.insert({arrival[it.first], it.first}); 80 | } 81 | } 82 | } 83 | } 84 | 85 | //Problem 1 (Direct Dijkstra): https://codeforces.com/contest/20/problem/C 86 | //Solution 1: http://codeforces.com/contest/20/submission/39892416 87 | 88 | //Problem 2: http://codeforces.com/contest/230/problem/D 89 | //Solution 2: http://codeforces.com/contest/230/submission/39892295 90 | 91 | //Problem 3 (count point on edges): https://codeforces.com/problemset/problem/144/D 92 | //Solution 3: https://codeforces.com/contest/144/submission/45963496 93 | 94 | //Problem 4 (all source Dijkstra): https://codeforces.com/contest/96/problem/D 95 | //Solution 4: https://codeforces.com/contest/96/submission/45959572 96 | 97 | //Problem 5: https://p.ip.fi/woUJ (Lexicographically shortest path from U to V) 98 | -------------------------------------------------------------------------------- /Discrete Logarithm.cpp: -------------------------------------------------------------------------------- 1 | //Finds smallest x such that a^x mod m = b mod m, returns -1 if there is no such x 2 | //Complexity: O(sqrtM * logM) 3 | 4 | long long pow(long long a, long long b, long long m) 5 | { 6 | long long ans=1; 7 | while(b) 8 | { 9 | if(b&1) 10 | ans=(ans*a)%m; 11 | b/=2; 12 | a=(a*a)%m; 13 | } 14 | return ans; 15 | } 16 | 17 | int discreteLog(int a, int b, int m) 18 | { 19 | a %= m, b %= m; 20 | if(b == 1) 21 | return 0; 22 | int cnt = 0; 23 | long long t = 1; 24 | for(int curg=__gcd(a, m);curg!=1;curg=__gcd(a, m)) 25 | { 26 | if(b % curg) 27 | return -1; 28 | b /= curg, m /= curg, t = (t * a / curg) % m; 29 | cnt++; 30 | if(b == t) 31 | return cnt; 32 | } 33 | 34 | map hash; 35 | int mid = ((int)sqrt(1.0 * m) + 1); 36 | long long base = b; 37 | for(int i=0;i 57 | #include 58 | using namespace __gnu_pbds; 59 | using namespace std; 60 | 61 | #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); 62 | #define endl "\n" 63 | #define int long long 64 | 65 | long long pow(long long a, long long b, long long m) 66 | { 67 | long long ans=1; 68 | while(b) 69 | { 70 | if(b&1) 71 | ans=(ans*a)%m; 72 | b/=2; 73 | a=(a*a)%m; 74 | } 75 | return ans; 76 | } 77 | 78 | int discreteLog(int a, int b, int m) 79 | { 80 | a %= m, b %= m; 81 | if(b == 1) 82 | return 0; 83 | int cnt = 0; 84 | long long t = 1; 85 | for(int curg=__gcd(a, m);curg!=1;curg=__gcd(a, m)) 86 | { 87 | if(b % curg) 88 | return -1; 89 | b /= curg, m /= curg, t = (t * a / curg) % m; 90 | cnt++; 91 | if(b == t) 92 | return cnt; 93 | } 94 | 95 | gp_hash_table hash; 96 | int mid = ((int)sqrt(1.0 * m) + 1); 97 | long long base = b; 98 | for(int i=0;isecond + cnt; 112 | } 113 | } 114 | 115 | //Problem 1: https://codeforces.com/gym/101853/problem/G 116 | //Solution 1: https://codeforces.com/gym/101853/submission/50273547 117 | 118 | //Problem 2: https://www.spoj.com/problems/MOD/ 119 | //Solution 2: http://p.ip.fi/9xAa 120 | -------------------------------------------------------------------------------- /MaxFlow - Push Relabel [V^2 sqrt(E)].cpp: -------------------------------------------------------------------------------- 1 | //Push-Relabel Algorithm for Flows, Complexity: O(V^2 √E) 2 | //To obtain the actual flow values, look at all edges with capacity > 0 3 | //Zero capacity edges are residual edges 4 | 5 | struct edge 6 | { 7 | int from, to, cap, flow, index; 8 | edge(int from, int to, int cap, int flow, int index): 9 | from(from), to(to), cap(cap), flow(flow), index(index) {} 10 | }; 11 | 12 | struct PushRelabel 13 | { 14 | static const long long INF=1e18; 15 | 16 | int n; 17 | vector > g; 18 | vector excess; 19 | vector height; 20 | 21 | PushRelabel(int n): 22 | n(n), g(n), excess(n), height(n) {} 23 | 24 | void addEdge(int from, int to, int cap) 25 | { 26 | g[from].push_back(edge(from, to, cap, 0, g[to].size())); 27 | if(from==to) 28 | g[from].back().index++; 29 | g[to].push_back(edge(to, from, 0, 0, g[from].size()-1)); 30 | } 31 | 32 | void push(edge &e) 33 | { 34 | int amt=(int)min(excess[e.from], (long long)e.cap - e.flow); 35 | if(height[e.from]<=height[e.to] || amt==0) 36 | return; 37 | e.flow += amt; 38 | g[e.to][e.index].flow -= amt; 39 | excess[e.to] += amt; 40 | excess[e.from] -= amt; 41 | } 42 | 43 | void relabel(int u) 44 | { 45 | int d=2e5; 46 | for(auto &it:g[u]) 47 | { 48 | if(it.cap-it.flow>0) 49 | d=min(d, height[it.to]); 50 | } 51 | if(d find_max_height_vertices(int source, int dest) 56 | { 57 | vector max_height; 58 | for(int i=0;i0) 61 | { 62 | if(!max_height.empty() && height[i] > height[max_height[0]]) 63 | max_height.clear(); 64 | if(max_height.empty() || height[i] == height[max_height[0]]) 65 | max_height.push_back(i); 66 | } 67 | } 68 | return max_height; 69 | } 70 | 71 | long long max_flow(int source, int dest) 72 | { 73 | excess.assign(n, 0); 74 | height.assign(n, 0); 75 | height[source]=n; 76 | excess[source]=INF; 77 | for(auto &it:g[source]) 78 | push(it); 79 | 80 | vector current; 81 | while(!(current = find_max_height_vertices(source, dest)).empty()) 82 | { 83 | for(auto i:current) 84 | { 85 | bool pushed=false; 86 | for(auto &e:g[i]) 87 | { 88 | if(excess[i]==0) 89 | break; 90 | if(e.cap - e.flow>0 && height[e.from] == height[e.to] + 1) 91 | { 92 | push(e); 93 | pushed=true; 94 | } 95 | } 96 | if(!pushed) 97 | { 98 | relabel(i); 99 | break; 100 | } 101 | } 102 | } 103 | 104 | long long max_flow=0; 105 | for(auto &e:g[source]) 106 | max_flow+=e.flow; 107 | 108 | return max_flow; 109 | } 110 | }; 111 | 112 | //Problem 1: http://codeforces.com/contest/546/problem/E 113 | //Solution 1: http://codeforces.com/contest/546/submission/40528334 114 | -------------------------------------------------------------------------------- /suffixArray.cpp: -------------------------------------------------------------------------------- 1 | // Untested. 2 | 3 | #include 4 | using namespace std; 5 | 6 | #define fo(i,n) for(i=0;i<(n);++i) 7 | #define repA(i,j,n) for(i=(j);i<=(n);++i) 8 | #define repD(i,j,n) for(i=(j);i>=(n);--i) 9 | #define all(x) begin(x), end(x) 10 | #define sz(x) (int)(x).size() 11 | #define pb push_back 12 | #define mp make_pair 13 | #define X first 14 | #define Y second 15 | #define endl "\n" 16 | 17 | typedef long long int lli; 18 | typedef long double mytype; 19 | typedef pair ii; 20 | typedef vector vii; 21 | typedef vector vi; 22 | 23 | // Credits - https://codeforces.com/contest/963/submission/37425722 24 | 25 | void count_sort(vector> &b, int bits) { // (optional) 26 | //this is just 3 times faster than stl sort for N=10^6 27 | int mask = (1 << bits) - 1; 28 | for(int it = 0; it < 2; ++it) 29 | { 30 | int move = it * bits; 31 | vi q(1 << bits), w(sz(q) + 1); 32 | for(int i = 0; i < sz(b); ++i) 33 | q[(b[i].first >> move) & mask]++; 34 | partial_sum(q.begin(), q.end(), w.begin() + 1); 35 | vector> res(b.size()); 36 | for(int i = 0; i < sz(b); ++i) 37 | res[w[(b[i].first >> move) & mask]++] = b[i]; 38 | swap(b, res); 39 | } 40 | } 41 | struct SuffixArray { 42 | vi a; 43 | string s; 44 | SuffixArray(const string& _s) : s(_s + '\0') { 45 | int N = sz(s); 46 | vector> b(N); 47 | a.resize(N); 48 | for(int i = 0; i < N; ++i) 49 | { 50 | b[i].first = s[i]; 51 | b[i].second = i; 52 | } 53 | 54 | int q = 8; 55 | while ((1 << q) < N) q++; 56 | for (int moc = 0;; moc++) { 57 | count_sort(b, q); // sort(all(b)) can be used as well 58 | a[b[0].second] = 0; 59 | for(int i = 1; i < N; ++i) 60 | a[b[i].second] = a[b[i - 1].second] + 61 | (b[i - 1].first != b[i].first); 62 | 63 | if ((1 << moc) >= N) break; 64 | for(int i = 0; i < N; ++i) { 65 | b[i].first = (lli)a[i] << q; 66 | if (i + (1 << moc) < N) 67 | b[i].first += a[i + (1 << moc)]; 68 | b[i].second = i; 69 | } 70 | } 71 | rep(i,0,sz(a)) a[i] = b[i].second; 72 | } 73 | int lower_bound(string t){ 74 | int l = 1,r=sz(a); 75 | while(l= t) r = m; 78 | else l = m+1; 79 | } 80 | return l; 81 | } 82 | int upper_bound(string t){ 83 | int l = 1,r=sz(a); 84 | while(l t) r = m; 87 | else l = m+1; 88 | } 89 | return l; 90 | } 91 | vi lcp() { 92 | // longest common prefixes: res[i] = lcp(a[i], a[i-1]) 93 | int n = sz(a), h = 0; 94 | vi inv(n), res(n); 95 | for(int i = 0; i 0) { 97 | int p0 = a[inv[i] - 1]; 98 | while (s[i + h] == s[p0 + h]) h++; 99 | res[inv[i]] = h; 100 | if(h > 0) h--; 101 | } 102 | return res; 103 | } 104 | }; 105 | 106 | int main() { 107 | return 0; 108 | } 109 | -------------------------------------------------------------------------------- /SQRT Decomposition.cpp: -------------------------------------------------------------------------------- 1 | const int SZ=sqrt(N); 2 | 3 | struct sqrtDecomposition 4 | { 5 | int L, R; 6 | int col[SZ], contrib[SZ]; 7 | bool lazy=0; 8 | int extra=0; 9 | int sumBlock=0; 10 | int lazyValue=0; 11 | 12 | void init(int l, int r) 13 | { 14 | for(int i=l;i<=r;i++) 15 | { 16 | col[i-l]=a[i]; 17 | contrib[i]=0; 18 | } 19 | L=l, R=r; 20 | extra=0; 21 | sumBlock=0; 22 | lazyValue=0; 23 | } 24 | 25 | void semiUpdate(int l, int r, int val) 26 | { 27 | if(l>r) 28 | return; 29 | if(lazy) 30 | { 31 | for(int i=L;i<=R;i++) 32 | { 33 | contrib[i-L]+=extra; 34 | col[i-L]=lazyValue; 35 | } 36 | lazy=0; 37 | extra=0; 38 | } 39 | for(int i=l;i<=r;i++) 40 | { 41 | sumBlock+=abs(val-col[i-L]); 42 | contrib[i-L]+=abs(val-col[i-L]); 43 | col[i-L]=val; 44 | } 45 | } 46 | 47 | void fullUpdate(int val) 48 | { 49 | if(lazy) 50 | { 51 | sumBlock+=(abs(val-lazyValue)*(R-L+1)); 52 | extra+=abs(val-lazyValue); 53 | } 54 | else 55 | { 56 | for(int i=L;i<=R;i++) 57 | { 58 | contrib[i-L]+=abs(col[i-L]-val); 59 | sumBlock+=abs(col[i-L]-val); 60 | col[i-L]=val; 61 | } 62 | } 63 | lazy=1; 64 | lazyValue=val; 65 | } 66 | 67 | void update(int l, int r, int val) 68 | { 69 | if(l<=L && r>=R) 70 | fullUpdate(val); 71 | else 72 | semiUpdate(max(l, L), min(r, R), val); 73 | } 74 | 75 | int semiQuery(int l, int r) 76 | { 77 | if(l>r) 78 | return 0; 79 | if(lazy) 80 | { 81 | for(int i=L;i<=R;i++) 82 | { 83 | contrib[i-L]+=extra; 84 | col[i-L]=lazyValue; 85 | } 86 | lazy=0; 87 | extra=0; 88 | } 89 | int answer=0; 90 | for(int i=l;i<=r;i++) 91 | answer+=contrib[i-L]; 92 | return answer; 93 | } 94 | 95 | int fullQuery() 96 | { 97 | return sumBlock; 98 | } 99 | 100 | int query(int l, int r) 101 | { 102 | if(l<=L && r>=R) 103 | return fullQuery(); 104 | else 105 | return semiQuery(max(l, L), min(r, R)); 106 | } 107 | 108 | }; 109 | 110 | sqrtDecomposition blocks[SZ+5]; 111 | 112 | void init() 113 | { 114 | int blcks=n/SZ + 1; 115 | int curL=1, curR=SZ; 116 | for(int i=1;i<=blcks;i++) 117 | { 118 | curR=min(curR, n); 119 | blocks[i].init(curL, curR); 120 | curL+=SZ; 121 | curR+=SZ; 122 | } 123 | } 124 | 125 | void update(int l, int r, int x) 126 | { 127 | int left=(l-1)/SZ + 1; 128 | int right=(r-1)/SZ + 1; 129 | for(int i=left;i<=right;i++) 130 | blocks[i].update(l, r, x); 131 | } 132 | 133 | int query(int l, int r) 134 | { 135 | int left=(l-1)/SZ + 1; 136 | int right=(r-1)/SZ + 1; 137 | int answer=0; 138 | for(int i=left;i<=right;i++) 139 | answer+=blocks[i].query(l, r); 140 | return answer; 141 | } 142 | 143 | //Problem 1: https://codeforces.com/contest/444/problem/C 144 | //Solution 1: https://codeforces.com/contest/444/submission/48887630 145 | 146 | //Problem 2 (Updating indices of a particular set): https://codeforces.com/contest/348/problem/C 147 | //Solution 2: https://codeforces.com/contest/348/submission/48511250 148 | -------------------------------------------------------------------------------- /Convex Hull (Dynamic).cpp: -------------------------------------------------------------------------------- 1 | //Original Code: https://www.codechef.com/viewsolution/8424830 2 | struct cht{ 3 | struct Line{ 4 | lli a; 5 | lli b; 6 | lli val; 7 | double xLeft; 8 | bool type; 9 | Line(lli _a = 0 , lli _b = 0){ 10 | a = _a; 11 | b = _b; 12 | xLeft = -INF; 13 | type = 0; 14 | val = 0; 15 | } 16 | lli valueAt(lli x) const{ 17 | return 1LL * a * x + b; 18 | } 19 | friend bool areParallel(const Line &l1, const Line &l2){ 20 | return l1.a == l2.a; 21 | } 22 | friend double intersectX(const Line &l1 , const Line &l2){ 23 | return areParallel(l1 , l2) ? INF : (l2.b - l1.b) / (double) (l1.a - l2.a); 24 | } 25 | bool operator < (const Line &l2) const{ 26 | if(!l2.type) 27 | return a < l2.a; 28 | return xLeft > l2.val; 29 | } 30 | }; 31 | set < Line > hull; 32 | void init(){ 33 | hull.clear(); 34 | } 35 | bool hasPrev(set < Line > :: iterator it){ 36 | return it != hull.begin(); 37 | } 38 | bool hasNext(set < Line > :: iterator it){ 39 | return it != hull.end() && next(it) != hull.end(); 40 | } 41 | bool irrelevant(const Line &l1 , const Line &l2 , const Line &l3){ 42 | return intersectX(l1,l3) <= intersectX(l1,l2); 43 | } 44 | bool irrelevant(set < Line > :: iterator it){ 45 | return hasPrev(it) && hasNext(it) && (irrelevant(*next(it) , *it , *prev(it))); 46 | } 47 | set < Line > :: iterator updateLeftBorder(set < Line > :: iterator it){ 48 | if(!hasNext(it)){ 49 | return it; 50 | } 51 | double val = intersectX(*it , *next(it)); 52 | Line buf(*it); 53 | it = hull.erase(it); 54 | buf.xLeft = val; 55 | it = hull.insert(it, buf); 56 | return it; 57 | } 58 | void addLine(lli a , lli b){ 59 | // dbg("add",a,b); 60 | Line l3 = Line(a, b); 61 | auto it = hull.lower_bound(l3); 62 | if(it != hull.end() && areParallel(*it , l3)){ 63 | if(it -> b > b){ 64 | it = hull.erase(it); 65 | } 66 | else{ 67 | return; 68 | } 69 | } 70 | it = hull.insert(it, l3); 71 | if(irrelevant(it)){ 72 | hull.erase(it); 73 | return; 74 | } 75 | while(hasPrev(it) && irrelevant(prev(it))){ 76 | hull.erase(prev(it)); 77 | } 78 | while(hasNext(it) && irrelevant(next(it))){ 79 | hull.erase(next(it)); 80 | } 81 | it = updateLeftBorder(it); 82 | if(hasPrev(it)){ 83 | updateLeftBorder(prev(it)); 84 | } 85 | if(hasNext(it)){ 86 | updateLeftBorder(next(it)); 87 | } 88 | } 89 | lli getBest(lli x){ 90 | // assert(!hull.empty()); 91 | if(hull.empty()) 92 | return INF; 93 | Line q; 94 | q.val = x; 95 | q.type = 1; 96 | auto bestLine = hull.lower_bound(q); 97 | if(bestLine == hull.end()){ 98 | return INF; 99 | } 100 | return bestLine -> valueAt(x); 101 | } 102 | }; 103 | 104 | //Problem 1: http://codeforces.com/contest/320/problem/E 105 | //Solution 1: http://codeforces.com/contest/320/submission/40481396 106 | -------------------------------------------------------------------------------- /Min Cost Max Flow - Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | //Works for negative costs, but does not work for negative cycles 2 | //Complexity: O(min(E^2 *V log V, E logV * flow)) 3 | 4 | struct edge 5 | { 6 | int to, flow, cap, cost, rev; 7 | }; 8 | 9 | struct MinCostMaxFlow 10 | { 11 | int nodes; 12 | vector prio, curflow, prevedge, prevnode, q, pot; 13 | vector inqueue; 14 | vector > graph; 15 | MinCostMaxFlow() {} 16 | 17 | MinCostMaxFlow(int n): nodes(n), prio(n, 0), curflow(n, 0), 18 | prevedge(n, 0), prevnode(n, 0), q(n, 0), pot(n, 0), inqueue(n, 0), graph(n) {} 19 | 20 | void addEdge(int source, int to, int capacity, int cost) 21 | { 22 | edge a = {to, 0, capacity, cost, (int)graph[to].size()}; 23 | edge b = {source, 0, 0, -cost, (int)graph[source].size()}; 24 | graph[source].push_back(a); 25 | graph[to].push_back(b); 26 | } 27 | 28 | void bellman_ford(int source, vector &dist) 29 | { 30 | fill(dist.begin(), dist.end(), INT_MAX); 31 | dist[source] = 0; 32 | int qt=0; 33 | q[qt++] = source; 34 | for(int qh=0;(qh-qt)%nodes!=0;qh++) 35 | { 36 | int u = q[qh%nodes]; 37 | inqueue[u] = false; 38 | for(auto &e : graph[u]) 39 | { 40 | if(e.flow >= e.cap) 41 | continue; 42 | int v = e.to; 43 | int newDist = dist[u] + e.cost; 44 | if(dist[v] > newDist) 45 | { 46 | dist[v] = newDist; 47 | if(!inqueue[v]) 48 | { 49 | inqueue[v] = true; 50 | q[qt++ % nodes] = v; 51 | } 52 | } 53 | } 54 | } 55 | } 56 | 57 | pair minCostFlow(int source, int dest, int maxflow) 58 | { 59 | bellman_ford(source, pot); 60 | int flow = 0; 61 | int flow_cost = 0; 62 | while(flow < maxflow) 63 | { 64 | priority_queue, vector >, greater > > q; 65 | q.push({0, source}); 66 | fill(prio.begin(), prio.end(), INT_MAX); 67 | prio[source] = 0; 68 | curflow[source] = INT_MAX; 69 | while(!q.empty()) 70 | { 71 | int d = q.top().first; 72 | int u = q.top().second; 73 | q.pop(); 74 | if(d != prio[u]) 75 | continue; 76 | for(int i=0;i= e.cap) 81 | continue; 82 | int newPrio = prio[u] + e.cost + pot[u] - pot[v]; 83 | if(prio[v] > newPrio) 84 | { 85 | prio[v] = newPrio; 86 | q.push({newPrio, v}); 87 | prevnode[v] = u; 88 | prevedge[v] = i; 89 | curflow[v] = min(curflow[u], e.cap - e.flow); 90 | } 91 | } 92 | } 93 | if(prio[dest] == INT_MAX) 94 | break; 95 | for(int i=0;i st; 14 | vector cLazy; 15 | vector lazy; 16 | 17 | void init(int n) 18 | { 19 | N = n; 20 | st.resize(4 * N + 5); 21 | cLazy.assign(4 * N + 5, false); 22 | lazy.assign(4 * N + 5, 0); 23 | } 24 | 25 | //Write reqd merge functions 26 | void merge(data &cur, data &l, data &r) 27 | { 28 | cur.mn = min(l.mn, r.mn); 29 | } 30 | 31 | //Handle lazy propagation appriopriately 32 | void propagate(int node, int L, int R) 33 | { 34 | if(L != R) 35 | { 36 | cLazy[node*2] = 1; 37 | cLazy[node*2 + 1] = 1; 38 | lazy[node*2] = lazy[node]; 39 | lazy[node*2 + 1] = lazy[node]; 40 | } 41 | st[node].mn = lazy[node]; 42 | cLazy[node] = 0; 43 | } 44 | 45 | void build(int node, int L, int R) 46 | { 47 | if(L==R) 48 | { 49 | st[node].mn = 1e9; 50 | return; 51 | } 52 | int M=(L + R)/2; 53 | build(node*2, L, M); 54 | build(node*2 + 1, M + 1, R); 55 | merge(st[node], st[node*2], st[node*2+1]); 56 | } 57 | 58 | data Query(int node, int L, int R, int i, int j) 59 | { 60 | if(cLazy[node]) 61 | propagate(node, L, R); 62 | if(jR) 63 | return data(); 64 | if(i<=L && R<=j) 65 | return st[node]; 66 | int M = (L + R)/2; 67 | data left=Query(node*2, L, M, i, j); 68 | data right=Query(node*2 + 1, M + 1, R, i, j); 69 | data cur; 70 | merge(cur, left, right); 71 | return cur; 72 | } 73 | 74 | data pQuery(int node, int L, int R, int pos) 75 | { 76 | if(cLazy[node]) 77 | propagate(node, L, R); 78 | if(L == R) 79 | return st[node]; 80 | int M = (L + R)/2; 81 | if(pos <= M) 82 | return pQuery(node*2, L, M, pos); 83 | else 84 | return pQuery(node*2 + 1, M + 1, R, pos); 85 | } 86 | 87 | void Update(int node, int L, int R, int i, int j, int val) 88 | { 89 | if(cLazy[node]) 90 | propagate(node, L, R); 91 | if(jR) 92 | return; 93 | if(i<=L && R<=j) 94 | { 95 | cLazy[node] = 1; 96 | lazy[node] = val; 97 | propagate(node, L, R); 98 | return; 99 | } 100 | int M = (L + R)/2; 101 | Update(node*2, L, M, i, j, val); 102 | Update(node*2 + 1, M + 1, R, i, j, val); 103 | merge(st[node], st[node*2], st[node*2 + 1]); 104 | } 105 | 106 | void pUpdate(int node, int L, int R, int pos, int val) 107 | { 108 | if(cLazy[node]) 109 | propagate(node, L, R); 110 | if(L == R) 111 | { 112 | cLazy[node] = 1; 113 | lazy[node] = val; 114 | propagate(node, L, R); 115 | return; 116 | } 117 | int M = (L + R)/2; 118 | if(pos <= M) 119 | pUpdate(node*2, L, M, pos, val); 120 | else 121 | pUpdate(node*2 + 1, M + 1, R, pos, val); 122 | merge(st[node], st[node*2], st[node*2 + 1]); 123 | } 124 | 125 | data query(int pos) 126 | { 127 | return pQuery(1, 1, N, pos); 128 | } 129 | 130 | data query(int l, int r) 131 | { 132 | return Query(1, 1, N, l, r); 133 | } 134 | 135 | void update(int pos, int val) 136 | { 137 | pUpdate(1, 1, N, pos, val); 138 | } 139 | 140 | void update(int l, int r, int val) 141 | { 142 | Update(1, 1, N, l, r, val); 143 | } 144 | }; 145 | 146 | //Problem 1 (Max Query - Point Update with Coordinate Compression): http://codeforces.com/gym/100733/problem/F 147 | //Solution 1: http://codeforces.com/gym/100733/submission/41643795 148 | 149 | //Problem 2 (Min Query - Offline processing): https://codeforces.com/problemset/problem/522/D 150 | //Solution 2: https://codeforces.com/contest/522/submission/45493164 151 | -------------------------------------------------------------------------------- /MaxFlow - Push Relabel [V^3].cpp: -------------------------------------------------------------------------------- 1 | //Push-Relabel Algorithm for Flows - Gap Heuristic, Complexity: O(V^3) 2 | //To obtain the actual flow values, look at all edges with capacity > 0 3 | //Zero capacity edges are residual edges 4 | 5 | struct edge 6 | { 7 | int from, to, cap, flow, index; 8 | edge(int from, int to, int cap, int flow, int index): 9 | from(from), to(to), cap(cap), flow(flow), index(index) {} 10 | }; 11 | 12 | struct PushRelabel 13 | { 14 | int n; 15 | vector > g; 16 | vector excess; 17 | vector height, active, count; 18 | queue Q; 19 | 20 | PushRelabel(int n): 21 | n(n), g(n), excess(n), height(n), active(n), count(2*n) {} 22 | 23 | void addEdge(int from, int to, int cap) 24 | { 25 | g[from].push_back(edge(from, to, cap, 0, g[to].size())); 26 | if(from==to) 27 | g[from].back().index++; 28 | g[to].push_back(edge(to, from, 0, 0, g[from].size()-1)); 29 | } 30 | 31 | void enqueue(int v) 32 | { 33 | if(!active[v] && excess[v] > 0) 34 | { 35 | active[v]=true; 36 | Q.push(v); 37 | } 38 | } 39 | 40 | void push(edge &e) 41 | { 42 | int amt=(int)min(excess[e.from], (long long)e.cap - e.flow); 43 | if(height[e.from]<=height[e.to] || amt==0) 44 | return; 45 | e.flow += amt; 46 | g[e.to][e.index].flow -= amt; 47 | excess[e.to] += amt; 48 | excess[e.from] -= amt; 49 | enqueue(e.to); 50 | } 51 | 52 | void relabel(int v) 53 | { 54 | count[height[v]]--; 55 | int d=2*n; 56 | for(auto &it:g[v]) 57 | { 58 | if(it.cap-it.flow>0) 59 | d=min(d, height[it.to]+1); 60 | } 61 | height[v]=d; 62 | count[height[v]]++; 63 | enqueue(v); 64 | } 65 | 66 | void gap(int k) 67 | { 68 | for(int v=0;v0 && i0) 84 | { 85 | if(count[height[v]]==1) 86 | gap(height[v]); 87 | else 88 | relabel(v); 89 | } 90 | } 91 | 92 | long long max_flow(int source, int dest) 93 | { 94 | count[0] = n-1; 95 | count[n] = 1; 96 | height[source] = n; 97 | active[source] = active[dest] = 1; 98 | for(auto &it:g[source]) 99 | { 100 | excess[source]+=it.cap; 101 | push(it); 102 | } 103 | 104 | while(!Q.empty()) 105 | { 106 | int v=Q.front(); 107 | Q.pop(); 108 | active[v]=false; 109 | discharge(v); 110 | } 111 | 112 | long long max_flow=0; 113 | for(auto &e:g[source]) 114 | max_flow+=e.flow; 115 | 116 | return max_flow; 117 | } 118 | }; 119 | 120 | //Original Source: https://github.com/jaehyunp/stanfordacm/blob/master/code/PushRelabel.cc 121 | 122 | //Problem 1: http://codeforces.com/contest/546/problem/E 123 | //Solution 1: http://codeforces.com/contest/546/submission/40660003 124 | 125 | //Problem 2: http://codeforces.com/contest/653/problem/D 126 | //Solution 2: http://codeforces.com/contest/653/submission/40659969 127 | 128 | //Problem 3 (Vertex Disjoint Chain with Path Printing): (K) http://codeforces.com/gym/101606/attachments/download/6242/2017-united-kingdom-ireland-programming-contest-ukiepc-2017-en.pdf 129 | //Solution 3: http://codeforces.com/gym/101606/submission/41992537 130 | 131 | //Problem 4: (Mincut = Maxflow) http://codeforces.com/gym/100733/problem/I 132 | //Solution 4: http://codeforces.com/gym/100733/submission/41993711 133 | 134 | //Problem 5: (Mincut on N plans): https://wcipeg.com/problem/noi06p4 135 | //Solution 5: http://p.ip.fi/KQt0 136 | -------------------------------------------------------------------------------- /FFT_jatin.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Ref - https://www.codechef.com/viewsolution/24509237 3 | 4 | typedef long long int ll; 5 | typedef vector vll; 6 | #define ld double 7 | 8 | // polynomial stuff 9 | struct base{ 10 | ld x,y; 11 | base(){x=y=0;} 12 | base(ld _x, ld _y){x = _x,y = _y;} 13 | base(ld _x){x = _x, y = 0;} 14 | void operator = (ld _x){x = _x,y = 0;} 15 | ld real(){return x;} 16 | ld imag(){return y;} 17 | base operator + (const base& b){return base(x+b.x,y+b.y);} 18 | void operator += (const base& b){x+=b.x,y+=b.y;} 19 | base operator * (const base& b){return base(x*b.x - y*b.y,x*b.y+y*b.x);} 20 | void operator *= (const base& b){ld p = x*b.x - y*b.y, q = x*b.y+y*b.x; x = p, y = q;} 21 | void operator /= (ld k){x/=k,y/=k;} 22 | base operator - (const base& b){return base(x - b.x,y - b.y);} 23 | void operator -= (const base& b){x -= b.x, y -= b.y;} 24 | base conj(){ return base(x, -y);} 25 | base operator / (ld k) { return base(x / k, y / k);} 26 | void Print(){ cerr << x << " + " << y << "i\n";} 27 | }; 28 | 29 | double PI = 2.0*acos(0.0); 30 | const int MAXN = 19; 31 | const int maxn = (1< & a, bool invert) { 44 | int n = (int) a.size(); 45 | 46 | for (int i=1, j=0; i> 1; 48 | for (; j>=bit; bit>>=1) 49 | j -= bit; 50 | j += bit; 51 | if (i < j) 52 | swap (a[i], a[j]); 53 | } 54 | for (int len=2; len<=n; len<<=1) { 55 | for (int i=0; i P(n), Q(n); 74 | const int SQRTMOD = (int)sqrt(mod) + 10; 75 | for(int i = 0;i < n1;i++) P[i] = base(a[i] % SQRTMOD, a[i] / SQRTMOD); 76 | for(int i = 0;i < n2;i++) Q[i] = base(b[i] % SQRTMOD, b[i] / SQRTMOD); 77 | fft(P, 0); 78 | fft(Q, 0); 79 | base A1, A2, B1, B2, X, Y; 80 | for(int i = 0; i < n; i++){ 81 | X = P[i]; 82 | Y = P[(n - i) % n].conj(); 83 | A1 = (X + Y) * base(0.5, 0); 84 | A2 = (X - Y) * base(0, -0.5); 85 | X = Q[i]; 86 | Y = Q[(n - i) % n].conj(); 87 | B1 = (X + Y) * base(0.5, 0); 88 | B2 = (X - Y) * base(0, -0.5); 89 | P1[i] = A1 * B1 + A2 * B2 * base(0, 1); 90 | Q1[i] = A1 * B2 + A2 * B1; 91 | } 92 | for(int i = 0; i < n; i++) P[i] = P1[i], Q[i] = Q1[i]; 93 | fft(P, 1); 94 | fft(Q, 1); 95 | a.resize(final_size); 96 | for(int i = 0; i < final_size; i++){ 97 | ll x = (ll)(P[i].real() + 0.5); 98 | ll y = (ll)(P[i].imag() + 0.5) % mod; 99 | ll z = (ll)(Q[i].real() + 0.5); 100 | a[i] = (x + ((y * SQRTMOD + z) % mod) * SQRTMOD) % mod; 101 | } 102 | } 103 | 104 | // Ensure all terms are positive. 105 | vll mul(vll a, vll b){ 106 | mul_big_mod(a, b); 107 | return a; 108 | } 109 | 110 | // Call this in main. 111 | precompute_powers(); 112 | -------------------------------------------------------------------------------- /Extra: -------------------------------------------------------------------------------- 1 | -AdHoc 2 | //Problem 1 (Pending): https://www.codechef.com/ICMT2019/problems/ICM08 3 | //Problem 2: https://www.codechef.com/DCC2019/problems/DCC4 4 | 5 | -BIT: 6 | //Problem 1 (Count of distinct elements): https://www.hackerrank.com/contests/university-codesprint-4/challenges/unique-art/problem 7 | //Solution 1: http://p.ip.fi/T9YM 8 | 9 | -BFS 10 | //Problem 1 (Multiple of number not containing some digits): https://www.spoj.com/problems/MULTII/ 11 | 12 | -Dealing with periodic repeats: 13 | 14 | //Problem 1: https://codeforces.com/problemset/problem/173/A 15 | //Problem 2: https://codeforces.com/contest/863/problem/C 16 | 17 | -DP Problems: 18 | 19 | //Problem 1: https://codeforces.com/contest/214/problem/D 20 | //Problem 2: https://codeforces.com/problemset/problem/137/D 21 | //Problem 3: https://codeforces.com/contest/229/problem/D 22 | //Problem 4 (Mutually Dependent Recurrence): https://www.hackerrank.com/challenges/alien-languages/problem 23 | 24 | -DP on Tree: 25 | //Problem 1 (Minimum Vertex Cover + Number of Ways): https://www.spoj.com/problems/VOCV/ 26 | //Problem 2 (Number of subtrees with diameter <=K): https://www.spoj.com/problems/CNTTREE/ 27 | //Problem 3: https://codeforces.com/problemset/problem/815/C 28 | //Problem 4 (Smaller to Larger merging): https://csacademy.com/contest/round-31/task/uniform-trees/ 29 | 30 | -DFS 31 | //Problem 1 (Virtual Nodes): https://codeforces.com/contest/821/problem/D 32 | //Problem 2 (Missing Edges): https://codeforces.com/contest/920/problem/E 33 | 34 | -DFS in 2D Grid: 35 | 36 | //Problem 1: https://codeforces.com/contest/616/problem/C 37 | 38 | (Probability): 39 | //Problem 1: https://codeforces.com/contest/513/problem/G2 40 | //Problem 2: https://www.codechef.com/GWR17ROL/problems/KALADIN/ 41 | //Problem 3: https://codeforces.com/contest/280/problem/C 42 | 43 | -GCD Inclusion Exclusion: 44 | 45 | //Problem 1: https://codeforces.com/contest/548/problem/E 46 | //Problem 2: https://codeforces.com/contest/839/problem/D 47 | //Problem 3: https://www.codechef.com/ONIG2019/problems/BIT_CSUM/ 48 | //Solution 3: https://www.codechef.com/viewsolution/23676665 49 | 50 | -Graph Theory: 51 | 52 | //Problem 1 (Diameter logic): https://codeforces.com/contest/337/problem/D 53 | //Problem 2 (Updating diameter): https://codeforces.com/problemset/problem/379/F 54 | //Problem 3: https://codeforces.com/contest/1040/problem/E 55 | //Problem 4: (DSU with Undo + Divide and Conquer): https://codeforces.com/contest/813/problem/F 56 | 57 | -Math; 58 | 59 | //Problem 1 (Pending): https://www.codechef.com/ICMT2019/problems/ICM06 60 | 61 | -Smart Greedy: 62 | 63 | //Problem 1: https://codeforces.com/contest/447/problem/D 64 | //Problem 2 (Own Comparator): https://codeforces.com/contest/922/standings/friends/true 65 | 66 | -Random Good Questions: 67 | 68 | //Problem 1 (Math): https://codeforces.com/contest/396/problem/B 69 | //Problem 2 (Binary Search with Consecutive Prefix Sums): https://codeforces.com/contest/837/problem/F 70 | //Problem 3 (DP with Consecutive Prefix Sums): https://codeforces.com/contest/57/problem/C 71 | //Problem 4 (Updating indices of a particular set): https://codeforces.com/contest/348/problem/C 72 | //Problem 5 (Perfect Powers in a range): https://codeforces.com/problemset/problem/955/C 73 | //Problem 6 (D length Jumps in Intervals): https://atcoder.jp/contests/arc068/tasks/arc068_c 74 | //Problem 7 (Converging K points to Median - Cost): https://www.codechef.com/viewsolution/23192706 75 | //Problem 8 (DFS with missing edges): https://codeforces.com/contest/653/problem/E 76 | //Problem 9 (Interactive - Tree Labelling): https://codeforces.com/contest/1075/problem/D 77 | 78 | -To Copy Paste in Future: 79 | //Problem 1 (Getting a sequence of + and - by using a sequence of - operationss): http://p.ip.fi/6t7b 80 | //Problem 2 (Number of ways to place elements such that adjacent are different and given L and R) : https://www.codechef.com/BLUP2019/problems/AHAPH/ 81 | 82 | Resources: 83 | https://www.careerbless.com/aptitude/qa/permutations_combinations_imp7.php 84 | -------------------------------------------------------------------------------- /Treap.cpp: -------------------------------------------------------------------------------- 1 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 2 | 3 | int getRand(int l, int r) 4 | { 5 | uniform_int_distribution uid(l, r); 6 | return uid(rng); 7 | } 8 | 9 | struct Treap 10 | { 11 | struct data 12 | { 13 | int priority, val, cnt; 14 | data *l, *r; 15 | 16 | data() 17 | { 18 | val = 0, cnt = 0, l = NULL, r = NULL; 19 | } 20 | 21 | data (int _val) 22 | { 23 | val = _val, cnt = 1; 24 | l = NULL, r = NULL; 25 | priority = getRand(1, 2e9); 26 | } 27 | }; 28 | 29 | typedef struct data* node; 30 | 31 | node head; 32 | 33 | Treap(): head(0) {} 34 | 35 | int cnt(node cur) 36 | { 37 | return cur ? cur->cnt : 0; 38 | } 39 | 40 | void updateCnt(node cur) 41 | { 42 | if(cur) 43 | cur->cnt = cnt(cur->l) + cnt(cur->r) + 1; 44 | } 45 | 46 | void push(node cur) //Lazy Propagation 47 | { 48 | ; 49 | } 50 | 51 | void combine(node &cur, node l, node r) 52 | { 53 | if(!l) 54 | { 55 | cur = r; 56 | return; 57 | } 58 | if(!r) 59 | { 60 | cur = l; 61 | return; 62 | } 63 | //Merge Operations like in segment tree 64 | } 65 | 66 | void reset(node &cur) //To reset other fields of cur except value and cnt 67 | { 68 | if(!cur) 69 | return; 70 | } 71 | 72 | void operation(node &cur) 73 | { 74 | if(!cur) 75 | return; 76 | reset(cur); 77 | combine(cur, cur->l, cur); 78 | combine(cur, cur, cur->r); 79 | } 80 | 81 | void splitPos(node cur, node &l, node &r, int k, int add = 0) 82 | { 83 | if(!cur) 84 | return void(l = r = 0); 85 | push(cur); 86 | int idx = add + cnt(cur->l); 87 | if(idx <= k) 88 | splitPos(cur->r, cur->r, r, k, idx + 1), l = cur; 89 | else 90 | splitPos(cur->l, l, cur->l, k, add), r = cur; 91 | updateCnt(cur); 92 | operation(cur); 93 | } 94 | 95 | void split(node cur, node &l, node &r, int k) 96 | { 97 | if(!cur) 98 | return void(l = r = 0); 99 | push(cur); 100 | int idx = cur -> val; 101 | if(idx <= k) 102 | split(cur->r, cur->r, r, k), l = cur; 103 | else 104 | split(cur->l, l, cur->l, k), r = cur; 105 | updateCnt(cur); 106 | operation(cur); 107 | } 108 | 109 | void merge(node &cur, node l, node r) 110 | { 111 | push(l); 112 | push(r); 113 | if(!l || !r) 114 | cur = l ? l : r; 115 | else if(l->priority > r->priority) 116 | merge(l->r, l->r, r), cur = l; 117 | else 118 | merge(r->l, l, r->l), cur = r; 119 | updateCnt(cur); 120 | operation(cur); 121 | } 122 | 123 | void insert(int val) 124 | { 125 | if(!head) 126 | { 127 | head = new data(val); 128 | return; 129 | } 130 | node l, r, mid, mid2, rr; 131 | mid = new data(val); 132 | split(head, l, r, val - 1); 133 | merge(l, l, mid); 134 | split(r, mid2, rr, val); 135 | merge(head, l, rr); 136 | } 137 | 138 | void erase(int val) 139 | { 140 | node l, r, mid; 141 | split(head, l, r, val - 1); 142 | split(r, mid, r, val); 143 | merge(head, l, r); 144 | } 145 | 146 | void inorder(node cur) 147 | { 148 | if(!cur) 149 | return; 150 | push(cur); 151 | inorder(cur->l); 152 | cout<val<<" "; 153 | inorder(cur->r); 154 | } 155 | 156 | void inorder() 157 | { 158 | inorder(head); 159 | cout<l), clear(cur->r); 167 | delete cur; 168 | } 169 | 170 | void clear() 171 | { 172 | clear(head); 173 | } 174 | 175 | int find_by_order(int x) //1 indexed 176 | { 177 | if(!x) 178 | return -1; 179 | x--; 180 | node l, r, mid; 181 | splitPos(head, l, r, x - 1); 182 | splitPos(r, mid, r, 0); 183 | int ans = -1; 184 | if(cnt(mid) == 1) 185 | ans = mid->val; 186 | merge(r, mid, r); 187 | merge(head, l, r); 188 | return ans; 189 | } 190 | 191 | int order_of_key(int val) //1 indexed 192 | { 193 | node l, r, mid; 194 | split(head, l, r, val - 1); 195 | split(r, mid, r, val); 196 | int ans = -1; 197 | if(cnt(mid) == 1) 198 | ans = 1 + cnt(l); 199 | merge(r, mid, r); 200 | merge(head, l, r); 201 | return ans; 202 | } 203 | }; 204 | 205 | //Problem 1: https://www.spoj.com/problems/ALLIN1/ 206 | //Solution 1: http://p.ip.fi/DOgq 207 | -------------------------------------------------------------------------------- /Heavy Light Decomposition (HLD).cpp: -------------------------------------------------------------------------------- 1 | 2 | const int N = 1e5+5; 3 | const int LG = log2(N) + 1; 4 | 5 | int n, tim=0; 6 | int a[N], level[N], tin[N], tout[N], rtin[N], nxt[N], subtree[N], parent[LG][N]; 7 | vector g[N]; 8 | 9 | //Heavy Light Decomposition 10 | 11 | void dfs(int u, int par, int lvl) 12 | { 13 | parent[0][u] = par; 14 | level[u] = lvl; 15 | for(auto &it:g[u]) 16 | { 17 | if(it==par) 18 | continue; 19 | dfs(it, u, lvl+1); 20 | } 21 | } 22 | 23 | void dfs1(int u, int par) 24 | { 25 | subtree[u] = 1; 26 | for(auto &it:g[u]) 27 | { 28 | if(it==par) 29 | continue; 30 | dfs1(it, u); 31 | subtree[u] += subtree[it]; 32 | if(subtree[it] > subtree[g[u][0]]) 33 | swap(it, g[u][0]); 34 | } 35 | } 36 | 37 | void dfs_hld(int u, int par) 38 | { 39 | tin[u] = ++tim; 40 | rtin[tim] = u; 41 | for(auto &v:g[u]) 42 | { 43 | if(v==par) 44 | continue; 45 | nxt[v] = (v==g[u][0] ? nxt[u]:v); 46 | dfs_hld(v, u); 47 | } 48 | tout[u] = tim; 49 | } 50 | 51 | //LCA 52 | 53 | int walk(int u, int h) 54 | { 55 | for(int i=LG-1;i>=0;i--) 56 | { 57 | if((h>>i) & 1) 58 | u = parent[i][u]; 59 | } 60 | return u; 61 | } 62 | 63 | void precompute() 64 | { 65 | for(int i=1;i=0;i--) 77 | { 78 | if((1<=0;i--) 86 | { 87 | if(parent[i][u] && parent[i][u]!=parent[i][v]) 88 | { 89 | u=parent[i][u]; 90 | v=parent[i][v]; 91 | } 92 | } 93 | return parent[0][u]; 94 | } 95 | 96 | int dist(int u, int v) 97 | { 98 | return level[u] + level[v] - 2 * level[LCA(u, v)]; 99 | } 100 | 101 | //Segment Tree 102 | 103 | int st[4*N], lazy[4*N]; 104 | 105 | void build(int node, int L, int R) 106 | { 107 | if(L==R) 108 | { 109 | st[node]=a[rtin[L]]; 110 | return; 111 | } 112 | int M=(L+R)/2; 113 | build(node*2, L, M); 114 | build(node*2+1, M+1, R); 115 | st[node]=min(st[node*2], st[node*2+1]); 116 | } 117 | 118 | void propagate(int node, int L, int R) 119 | { 120 | if(L!=R) 121 | { 122 | lazy[node*2]+=lazy[node]; 123 | lazy[node*2+1]+=lazy[node]; 124 | } 125 | st[node]+=lazy[node]; 126 | lazy[node]=0; 127 | } 128 | 129 | int query(int node, int L, int R, int i, int j) 130 | { 131 | if(lazy[node]) 132 | propagate(node, L, R); 133 | if(jR) 134 | return 1e9; 135 | if(i<=L && R<=j) 136 | return st[node]; 137 | int M=(L+R)/2; 138 | int left=query(node*2, L, M, i, j); 139 | int right=query(node*2 + 1, M+1, R, i, j); 140 | return min(left, right); 141 | } 142 | 143 | void update(int node, int L, int R, int i, int j, int val) 144 | { 145 | if(lazy[node]) 146 | propagate(node, L, R); 147 | if(jR) 148 | return; 149 | if(i<=L && R<=j) 150 | { 151 | lazy[node]+=val; 152 | propagate(node, L, R); 153 | return; 154 | } 155 | int M=(L+R)/2; 156 | update(node*2, L, M, i, j, val); 157 | update(node*2 + 1, M+1, R, i, j, val); 158 | st[node]=min(st[node*2], st[node*2 + 1]); 159 | } 160 | 161 | void upd(int l, int r, int val) 162 | { 163 | update(1, 1, n, l, r, val); 164 | } 165 | 166 | int get(int l, int r) 167 | { 168 | return query(1, 1, n, l, r); 169 | } 170 | //Utility Functions 171 | 172 | int query_up(int x, int y) //Assuming Y is an ancestor of X 173 | { 174 | int res = 0; 175 | while(nxt[x] != nxt[y]) 176 | { 177 | res += get(tin[nxt[x]], tin[x]); 178 | x = parent[0][nxt[x]]; 179 | } 180 | res += get(tin[y] + 1, tin[x]); //use tin[y] to include Y 181 | return res; 182 | } 183 | 184 | int query_hld(int x, int y) 185 | { 186 | int lca = LCA(x, y); 187 | int res = query_up(x, lca) + query_up(y, lca); 188 | return res; 189 | } 190 | 191 | void update_up(int x, int y, int val) //Assuming Y is an ancestor of X 192 | { 193 | while(nxt[x] != nxt[y]) 194 | { 195 | upd(tin[nxt[x]], tin[x], val); 196 | x = parent[0][nxt[x]]; 197 | } 198 | upd(tin[y] + 1, tin[x], val); //use tin[y] to include Y 199 | } 200 | 201 | void update_hld(int x, int y, int val) 202 | { 203 | int lca = LCA(x, y); 204 | update_up(x, lca, val); 205 | update_up(y, lca, val); 206 | } 207 | 208 | void hld() 209 | { 210 | dfs(1, 0, 1); 211 | dfs1(1, 0); 212 | dfs_hld(1, 0); 213 | precompute(); 214 | build(1, 1, n); 215 | } 216 | 217 | //Problem 1 (Maximum Climb for nodes with same value): https://www.codechef.com/CONA2019/problems/COMA19E 218 | //Solution 1: https://www.codechef.com/viewsolution/23271645 219 | -------------------------------------------------------------------------------- /Sweep Line: Intersecting Line Segments.cpp: -------------------------------------------------------------------------------- 1 | /*Returns pair of indices of any two intersecting line segments if there exist intersecting line segments, 2 | and (-1, -1) if no line segments intersect.*/ 3 | 4 | const double EPS = 1e-15; 5 | 6 | struct Point 7 | { 8 | double x, y; 9 | 10 | Point() 11 | { 12 | x = 0, y = 0; 13 | } 14 | 15 | Point(double _x, double _y) 16 | { 17 | x = _x, y = _y; 18 | } 19 | 20 | bool between(Point &P, Point &Q) 21 | { 22 | bool checkX = x < max(P.x, Q.x) + EPS && x + EPS > min(P.x, Q.x); 23 | bool checkY = y < max(P.y, Q.y) + EPS && y + EPS > min(P.y, Q.y); 24 | return checkX && checkY; 25 | } 26 | 27 | Point operator+ (const Point& P) const 28 | { 29 | return Point(x + P.x, y + P.y); 30 | } 31 | 32 | Point operator- (const Point& P) const 33 | { 34 | return Point(x - P.x, y - P.y); 35 | } 36 | 37 | bool operator< (Point &o) 38 | { 39 | if(abs(x - o.x) > EPS) 40 | return x < o.x; 41 | return y < o.y; 42 | } 43 | }; 44 | 45 | struct Line 46 | { 47 | double a, b, c; 48 | 49 | Line(Point P, Point Q) 50 | { 51 | if(abs(P.x - Q.x) < EPS) 52 | { 53 | a = 1; 54 | b = 0; 55 | c = -P.x; 56 | } 57 | else 58 | { 59 | a = (P.y - Q.y) / (Q.x - P.x); 60 | b = 1.0; 61 | c = -(a * P.x + P.y); 62 | } 63 | } 64 | 65 | bool parallel(Line l) 66 | { 67 | return abs(a - l.a) < EPS && abs(b - l.b) < EPS; 68 | } 69 | 70 | Point intersect(Line l) 71 | { 72 | if(parallel(l)) 73 | return Point(); 74 | double x = (b * l.c - c * l.b) / (a * l.b - b * l.a); 75 | double y; 76 | if(abs(b) < EPS) 77 | y = -l.a * x - l.c; 78 | else 79 | y = -a * x - c; 80 | } 81 | }; 82 | 83 | 84 | struct Segment 85 | { 86 | Point P, Q; 87 | int idx; 88 | 89 | Segment() 90 | { 91 | idx = -1; 92 | } 93 | 94 | Segment(double x1, double y1, double x2, double y2, int _idx) 95 | { 96 | P = Point(x1, y1); 97 | Q = Point(x2, y2); 98 | idx = _idx; 99 | } 100 | 101 | Segment(Point _P, Point _Q, int _idx) 102 | { 103 | P = _P, Q = _Q, idx = _idx; 104 | } 105 | 106 | Point intersect(Segment ls) 107 | { 108 | Line l1 = Line(P, Q); 109 | Line l2 = Line(ls.P, ls.Q); 110 | if(l1.parallel(l2)) 111 | return Point(); 112 | Point c = l1.intersect(l2); 113 | return c.between(P, Q) && c.between(ls.P, ls.Q) ? c : Point(); 114 | } 115 | 116 | double get_y(double &x) const 117 | { 118 | if(abs(P.x - Q.x) EPS) 136 | return x < e.x; 137 | if(type != e.type) 138 | return type > e.type; 139 | return idx < e.idx; 140 | } 141 | }; 142 | 143 | int vec(const Point &a, const Point &b, const Point &c) 144 | { 145 | double s = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); 146 | if(abs(s) < EPS) 147 | return 0; 148 | return s > 0 ? 1 : -1; 149 | } 150 | 151 | bool intersect1D(double l1, double r1, double l2, double r2) 152 | { 153 | if(l1 > r1) 154 | swap(l1, r1); 155 | if(l2 > r2) 156 | swap(l2, r2); 157 | return max(l1, l2) <= min(r1, r2) + EPS; 158 | } 159 | 160 | bool intersect(const Segment &a, const Segment &b) 161 | { 162 | return intersect1D(a.P.x, a.Q.x, b.P.x, b.Q.x) && 163 | intersect1D(a.P.y, a.Q.y, b.P.y, b.Q.y) && 164 | vec(a.P, a.Q, b.P) * vec(a.P, a.Q, b.Q) <= 0 && 165 | vec(b.P, b.Q, a.P) * vec(b.P, b.Q, a.Q) <=0; 166 | } 167 | 168 | bool operator<(const Segment& a, const Segment& b) 169 | { 170 | double x = max(min(a.P.x, a.Q.x), min(b.P.x, b.Q.x)); 171 | return a.get_y(x) < b.get_y(x) - EPS; 172 | } 173 | 174 | set s; 175 | vector::iterator > where; 176 | 177 | set::iterator prev(set::iterator it) 178 | { 179 | return it == s.begin() ? s.end() : --it; 180 | } 181 | 182 | set::iterator next(set::iterator it) 183 | { 184 | return ++it; 185 | } 186 | 187 | pair solve(const vector &v) 188 | { 189 | int n = v.size(); 190 | set events; 191 | for(int i=0;i::iterator nxt = s.lower_bound(v[idx]), prv = prev(nxt); 206 | if(nxt != s.end() && intersect(*nxt, v[idx])) 207 | return make_pair(nxt->idx, v[idx].idx); 208 | if(prv != s.end() && intersect(*prv, v[idx])) 209 | return make_pair(prv->idx, v[idx].idx); 210 | where[idx] = s.insert(nxt, v[idx]); 211 | } 212 | else 213 | { 214 | set::iterator nxt = next(where[idx]), prv = prev(where[idx]); 215 | if(nxt != s.end() && prv != s.end() && intersect(*nxt, *prv)) 216 | return make_pair(prv->idx, nxt->idx); 217 | s.erase(where[idx]); 218 | } 219 | } 220 | return make_pair(-1, -1); 221 | } 222 | 223 | //Problem 1: http://acm.timus.ru/problem.aspx?space=1&num=1469 224 | //Solution 1: http://p.ip.fi/hRY9 225 | -------------------------------------------------------------------------------- /FFT (Iterative).cpp: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------------------------------------------------------------------- 2 | 4 Call FFT with MOD: 3 | 4 | typedef complex base; 5 | 6 | const double PI = acos(-1.0l); 7 | const int N = 8e5+5; 8 | const int Maxb = 19; 9 | const int Maxp = 450; 10 | const int MOD=13313; 11 | 12 | vector rev; 13 | vector omega; 14 | 15 | void calc_rev(int n, int log_n) //Call this before FFT 16 | { 17 | omega.assign(n, 0); 18 | rev.assign(n, 0); 19 | for(int i=0;i>j)&1) 25 | rev[i] |= 1<<(log_n-j-1); 26 | } 27 | } 28 | } 29 | 30 | void fft(vector &A, int n, bool invert) 31 | { 32 | for(int i=0;i>1); 41 | 42 | base curomega(cos(ang), sin(ang)); 43 | omega[0]=base(1, 0); 44 | 45 | for(int i=1;i &A, vector &B, vector &C) 70 | { 71 | fft(A, n, false); 72 | fft(B, n, false); 73 | for(int i=0;i &coeffA, vector &coeffB, vector &result, bool big1, bool big2) //Call 4 times: 00, 01, 10, 11 84 | { 85 | vector A(n), B(n); 86 | for(int i=0;i C(n); 96 | multiply(n, A, B, C); 97 | for(int i=0;i &A, vector &B, vector &result) 111 | { 112 | int n=1, bits=0; 113 | while(n<2*A.size() || n<2*B.size()) 114 | n<<=1, bits++; 115 | result.assign(n, 0); 116 | calc_rev(n, bits); 117 | vector tempA(A.begin(), A.end()); 118 | vector tempB(B.begin(), B.end()); 119 | tempA.resize(n); 120 | tempB.resize(n); 121 | for(int i=0;i<2;i++) 122 | { 123 | for(int j=0;j<2;j++) 124 | { 125 | Solve(n, tempA, tempB, result, i, j); 126 | } 127 | } 128 | } 129 | 130 | ---------------------------------------------------------------------------------------------------------------------------------------- 131 | Single Call without MOD: 132 | 133 | typedef complex base; 134 | 135 | const double PI = acos(-1.0l); 136 | const int N = 8e5+5; 137 | const int Maxb = 19; 138 | const int Maxp = 450; 139 | const int MOD=13313; 140 | 141 | vector rev; 142 | vector omega; 143 | 144 | void calc_rev(int n, int log_n) //Call this before FFT 145 | { 146 | omega.assign(n, 0); 147 | rev.assign(n, 0); 148 | for(int i=0;i>j)&1) 154 | rev[i] |= 1<<(log_n-j-1); 155 | } 156 | } 157 | } 158 | 159 | void fft(vector &A, int n, bool invert) 160 | { 161 | for(int i=0;i>1); 170 | 171 | base curomega(cos(ang), sin(ang)); 172 | omega[0]=base(1, 0); 173 | 174 | for(int i=1;i &A, vector &B, vector &C) 199 | { 200 | fft(A, n, false); 201 | fft(B, n, false); 202 | for(int i=0;i &coeffA, vector &coeffB, vector &result) 213 | { 214 | vector A(n), B(n); 215 | for(int i=0;i C(n); 225 | multiply(n, A, B, C); 226 | for(int i=0;i &A, vector &B, vector &result) 234 | { 235 | int n=1, bits=0; 236 | while(n<2*A.size() || n<2*B.size()) 237 | n<<=1, bits++; 238 | result.assign(n, 0); 239 | calc_rev(n, bits); 240 | vector tempA(A.begin(), A.end()); 241 | vector tempB(B.begin(), B.end()); 242 | tempA.resize(n); 243 | tempB.resize(n); 244 | Solve(n, tempA, tempB, result); 245 | } 246 | 247 | //Problem 1: https://www.codechef.com/problems/COUNTWAY/ 248 | //Solution 1 (Divide and Conquer): https://www.codechef.com/viewsolution/19144054 249 | 250 | //Problem 2: https://codeforces.com/contest/993/problem/E 251 | //Solution 2: https://codeforces.com/contest/993/submission/40115289 252 | 253 | //Problem 3: https://codeforces.com/contest/954/problem/I 254 | //Solution 3: https://codeforces.com/contest/954/submission/40926618 255 | -------------------------------------------------------------------------------- /Geo Snippet.cpp: -------------------------------------------------------------------------------- 1 | // Ref - https://ideone.com/NYur1v 2 | 3 | 4 | p2? returns: 1 left, 0 on, -1 right 55 | double sg = (p1.x-p3.x)*(p2.y-p3.y)-(p1.y - p3.y)*(p2.x-p3.x); 56 | if(fabs(sg)0) return 1; 58 | return -1; 59 | } 60 | 61 | bool better(PT& p1,PT& p2,PT& p3){ 62 | // used by convec hull: from p3, if p1 is better than p2 63 | double sg = (p1.y - p3.y)*(p2.x-p3.x)-(p1.x-p3.x)*(p2.y-p3.y); 64 | //watch range of the numbers 65 | if(fabs(sg)dist(p3,p2))return true; 67 | else return false; 68 | } 69 | if(sg<0) return true; 70 | return false; 71 | } 72 | 73 | void vex2(vector vin,vector& vout){ 74 | // vin is not pass by reference, since we will rotate it 75 | vout.clear(); 76 | int n=vin.size(); 77 | sort(vin.begin(),vin.end()); 78 | PT stk[MAX_SIZE]; 79 | int pstk, i; 80 | // hopefully more than 2 points 81 | stk[0] = vin[0]; 82 | stk[1] = vin[1]; 83 | pstk = 2; 84 | for(i=2; i 1 && better(vin[i], stk[pstk-1], stk[pstk-2])) 87 | pstk--; 88 | stk[pstk] = vin[i]; 89 | pstk++; 90 | } 91 | for(i=0; i 1 && better(vin[i], stk[pstk-1], stk[pstk-2])) 104 | pstk--; 105 | stk[pstk] = vin[i]; 106 | pstk++; 107 | } 108 | for(i=1; i& v){ 116 | // test whether a simple polygon is convex 117 | // return 0 if not convex, 1 if strictly convex, 118 | // 2 if convex but there are points unnecesary 119 | // this function does not work if the polycon is self intersecting 120 | // in that case, compute the convex hull of v, and see if both have the same area 121 | int i,j,k; 122 | int c1=0; int c2=0; int c0=0; 123 | int n=v.size(); 124 | for(i=0;i0) c1++; 130 | if(s<0) c2++; 131 | } 132 | if(c1 && c2) return 0; 133 | if(c0) return 2; 134 | return 1; 135 | } 136 | 137 | // =============================================================== 138 | // Areas 139 | // =============================================================== 140 | double trap(PT a, PT b){ 141 | // Used in various area functions 142 | return (0.5*(b.x - a.x)*(b.y + a.y)); 143 | } 144 | double area(vector &vin){ 145 | // Area of a simple polygon, not neccessary convex 146 | int n = vin.size(); 147 | double ret = 0.0; 148 | for(int i = 0; i < n; i++) ret += trap(vin[i], vin[(i+1)%n]); 149 | return fabs(ret); 150 | } 151 | double peri(vector &vin){ 152 | // Perimeter of a simple polygon, not neccessary convex 153 | int n = vin.size(); 154 | double ret = 0.0; 155 | for(int i = 0; i < n; i++) ret += dist(vin[i], vin[(i+1)%n]); 156 | return ret; 157 | } 158 | 159 | double triarea(PT a, PT b, PT c){ 160 | return fabs(trap(a,b)+trap(b,c)+trap(c,a)); 161 | } 162 | 163 | double height(PT a, PT b, PT c){ 164 | // height from a to the line bc 165 | double s3 = dist(c, b); 166 | double ar=triarea(a,b,c); 167 | return(2.0*ar/s3); 168 | } 169 | 170 | // ==================================================== 171 | // Points and Lines 172 | // ==================================================== 173 | int intersection( PT p1, PT p2, PT p3, PT p4, PT &r ) { 174 | // two lines given by p1->p2, p3->p4 r is the intersection point 175 | // return -1 if two lines are parallel 176 | double d = (p4.y - p3.y)*(p2.x-p1.x) - (p4.x - p3.x)*(p2.y - p1.y); 177 | if( fabs( d ) < EPS ) return -1; 178 | // might need to do something special!!! 179 | double ua, ub; 180 | ua = (p4.x - p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x); 181 | ua /= d; 182 | // ub = (p2.x - p1.x)*(p1.y-p3.y) - (p2.y-p1.y)*(p1.x-p3.x); 183 | //ub /= d; 184 | r = p1 + (p2-p1)*ua; 185 | return 0; 186 | } 187 | 188 | void closestpt( PT p1, PT p2, PT p3, PT &r ){ 189 | // the closest point on the line p1->p2 to p3 190 | if( fabs( triarea( p1, p2, p3 ) ) < EPS ) { r = p3; return; } 191 | PT v = p2-p1; 192 | v.normalize(); 193 | double pr; // inner product 194 | pr = (p3.y-p1.y)*v.y + (p3.x-p1.x)*v.x; 195 | r = p1+v*pr; 196 | } 197 | 198 | int hcenter( PT p1, PT p2, PT p3, PT& r ){ 199 | // point generated by altitudes 200 | if( triarea( p1, p2, p3 ) < EPS ) return -1; 201 | PT a1, a2; 202 | closestpt( p2, p3, p1, a1 ); 203 | closestpt( p1, p3, p2, a2 ); 204 | intersection( p1, a1, p2, a2, r ); 205 | return 0; 206 | } 207 | int center( PT p1, PT p2, PT p3, PT& r ){ 208 | // point generated by circumscribed circle 209 | if( triarea( p1, p2, p3 ) < EPS ) return -1; 210 | PT a1, a2, b1, b2; 211 | a1 = (p2+p3)*0.5; 212 | a2 = (p1+p3)*0.5; 213 | b1.x = a1.x - (p3.y-p2.y); 214 | b1.y = a1.y + (p3.x-p2.x); 215 | b2.x = a2.x - (p3.y-p1.y); 216 | b2.y = a2.y + (p3.x-p1.x); 217 | intersection( a1, b1, a2, b2, r ); 218 | return 0; 219 | } 220 | 221 | int bcenter( PT p1, PT p2, PT p3, PT& r ){ 222 | // angle bisection 223 | if( triarea( p1, p2, p3 ) < EPS ) return -1; 224 | double s1, s2, s3; 225 | s1 = dist( p2, p3 ); 226 | s2 = dist( p1, p3 ); 227 | s3 = dist( p1, p2 ); 228 | double rt = s2/(s2+s3); 229 | PT a1,a2; 230 | a1 = p2*rt+p3*(1.0-rt); 231 | rt = s1/(s1+s3); 232 | a2 = p1*rt+p3*(1.0-rt); 233 | intersection( a1,p1, a2,p2, r ); 234 | return 0; 235 | } 236 | 237 | // =============================================== 238 | // Angles 239 | // =============================================== 240 | double angle(PT& p1, PT& p2, PT& p3){ 241 | // angle from p1->p2 to p1->p3, returns -PI to PI 242 | PT va = p2-p1; 243 | va.normalize(); 244 | PT vb; vb.x=-va.y; vb.y=va.x; 245 | PT v = p3-p1; 246 | double x,y; 247 | x=dot(v, va); 248 | y=dot(v, vb); 249 | return(atan2(y,x)); 250 | } 251 | 252 | double angle(double a, double b, double c){ 253 | // in a triangle with sides a,b,c, the angle between b and c 254 | // we do not check if a,b,c is a triangle here 255 | double cs=(b*b+c*c-a*a)/(2.0*b*c); 256 | return(acos(cs)); 257 | } 258 | 259 | void rotate(PT p0, PT p1, double a, PT& r){ 260 | // rotate p1 around p0 clockwise, by angle a 261 | // don’t pass by reference for p1, so r and p1 can be the same 262 | p1 = p1-p0; 263 | r.x = cos(a)*p1.x-sin(a)*p1.y; 264 | r.y = sin(a)*p1.x+cos(a)*p1.y; 265 | r = r+p0; 266 | } 267 | 268 | void reflect(PT& p1, PT& p2, PT p3, PT& r){ 269 | // p1->p2 line, reflect p3 to get r. 270 | if(dist(p1, p3)p2. 282 | // 1 if point is on the segment; 0 if not on the line; -1 if on the line but not on the segment 283 | double s=triarea(p, p1, p2); 284 | if(s>EPS) return(0); 285 | double sg=(p.x-p1.x)*(p.x-p2.x); 286 | if(sg>EPS) return(-1); 287 | sg=(p.y-p1.y)*(p.y-p2.y); 288 | if(sg>EPS) return(-1); 289 | return(1); 290 | } 291 | 292 | int lineAndCircle(PT& oo, double r, PT& p1, PT& p2, PT& r1, PT& r2){ 293 | // returns -1 if there is no intersection 294 | // returns 1 if there is only one intersection 295 | PT m; 296 | closestpt(p1,p2,oo,m); 297 | PT v = p2-p1; 298 | v.normalize(); 299 | double r0=dist(oo, m); 300 | if(r0>r+EPS) return -1; 301 | if(fabs(r0-r)r1+r2+EPS) return(-1); 320 | if(r pv, PT p){ 333 | // the relation of the point and the simple polygon 334 | // 1 if p is in pv; 0 outside; -1 on the polygon 335 | int i, j; 336 | int n=pv.size(); 337 | pv.push_back(pv[0]); 338 | for(i=0;i0) j++; 355 | } 356 | return(j%2); 357 | } 358 | } 359 | return 1; 360 | } 361 | 362 | 363 | ]]> 364 | 365 | geometry 366 | 367 | 368 | 369 | --------------------------------------------------------------------------------