├── README.md ├── numberTheory ├── etf.cpp ├── nCrModP_pascal.cpp ├── nCr.cpp ├── sieve_fast.cpp ├── nCrModP.cpp ├── modular_multiplicative_inverse.cpp ├── LinearModularEquation.cpp ├── discreteLog.cpp ├── modexpo.cpp └── matrix_expo.cpp ├── dp ├── kadane.cpp ├── kadaneIdx.cpp ├── CoinChange.cpp ├── Coin_ways.cpp ├── catalanNumber.cpp ├── maxSumRectangle.cpp ├── LCS_spaceOptimized.cpp ├── LCS.cpp ├── LIS_LDS_BTS.cpp └── subMatrixWithAll1s.cpp ├── DataStructures ├── BIT │ ├── BIT1.c │ ├── BIT2.c │ ├── inversion_count.cpp │ └── BIT3.c ├── Union_Find.cpp ├── stack │ └── Histogram.cpp ├── sparse table │ ├── 1D_RMQ.cpp │ └── 2D_RMQ.cpp └── segmentTree │ ├── rangeSumSegmentTree.cpp │ └── 2dSegmentTree.cpp ├── graph ├── DFS.cpp ├── BFS.cpp ├── cycleDetection_undirectedGraph.cpp ├── cycleDetection_directedGraph.cpp ├── bridges.cpp ├── flloydWarshall.cpp ├── checkEuler.cpp ├── dijikstra.cpp ├── kosaraju_SCC.cpp ├── bellmanFord.cpp ├── topologicalSort.cpp ├── Kruskal_MST.cpp ├── LCA_logn.cpp ├── 0-1BFS.cpp ├── checkBridge.cpp ├── check_bipartite.cpp ├── articulationPoint.cpp └── LCA_new.cpp ├── template.cpp ├── LICENSE ├── stringTheory ├── KMP.cpp └── trie.cpp ├── linearAlgebra └── gaussian_elimination.cpp ├── computational geometry └── closest point pair.cpp └── bigint.cpp /README.md: -------------------------------------------------------------------------------- 1 | algorepo 2 | ======== 3 | 4 | implementations of standard algorithms and data structures 5 | 6 | ###Issues 7 | 8 | Feel free to submit issues and enhancement requests. 9 | 10 | ###Contributing 11 | 12 | Please follow the "fork-and-pull" Git workflow. 13 | 14 | 1. Fork the repo on GitHub 15 | 2. Commit changes to a branch in your fork 16 | 3. Pull request "upstream" with your changes 17 | 4. Merge changes in to "upstream" repo 18 | 19 | NOTE: Be sure to merge the latest from "upstream" before making a pull request! 20 | -------------------------------------------------------------------------------- /numberTheory/etf.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int MAX = 100010; 5 | int phi[MAX]; 6 | 7 | void prePhi() //O(NlogN) precomputation of phi 8 | { 9 | 10 | for (int i = 1; i < MAX; i++) phi[i] = i; 11 | for (int i = 2; i < MAX; i++) 12 | if (phi[i] == i) 13 | { 14 | phi[i]--; 15 | for (int j = i * 2; j < MAX; j += i) 16 | phi[j] -= phi[j] / i; 17 | } 18 | } 19 | 20 | 21 | int main() 22 | { 23 | prePhi(); 24 | for(int i = 0; i < 10; i++) 25 | cout << phi[i] << " "; 26 | cout << endl; 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /dp/kadane.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int kadane(int *a, int n) 5 | { 6 | /* 7 | returns the maximum sum subArray 8 | Complexity: O(n) 9 | */ 10 | int max_ending_here = a[0], max_so_far = a[0]; 11 | for(int i = 1; i < n; i++) 12 | { 13 | max_ending_here = max(a[i], max_ending_here + a[i]); 14 | max_so_far = max(max_so_far, max_ending_here); 15 | } 16 | return max_so_far; 17 | 18 | } 19 | 20 | int main() 21 | { 22 | int a[] = {2, -2, -1, 4, 0, -7, 8}; 23 | int n = sizeof(a)/sizeof(int); 24 | int maxSumSubarray = kadane(a, n); 25 | cout << maxSumSubarray << endl; 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /numberTheory/nCrModP_pascal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define lli long long 3 | using namespace std; 4 | 5 | const int MOD = 1e9+7; 6 | const int MAX = 1010; 7 | 8 | lli c[MAX][MAX]; 9 | void pre() //calculates nCr % P using pascals triangle in O(n^2) time 10 | { 11 | c[0][0] = 1; 12 | for(int i = 1; i < MAX; i++) 13 | { 14 | c[i][0] = 1; 15 | for(int j = 1; j <= i; j++) 16 | c[i][j] = (c[i-1][j-1] + c[i-1][j]) % MOD; 17 | } 18 | } 19 | 20 | int main() 21 | { 22 | pre(); //do the MATH 23 | 24 | int n, r; 25 | scanf("%d %d", &n , &r); 26 | 27 | printf("(%dC%d)%%%d is %lld\n", n, r,MOD, c[n][r]); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /numberTheory/nCr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define lli long long 3 | using namespace std; 4 | 5 | const int MOD = 1e9+7; 6 | const int MAX = 200010; 7 | 8 | //NOTE: factorial(30) doesn't fit in 64bit integer but 9 | // using below fn we can compute C(61, r) [this is the upperbound] 10 | 11 | //IMP: No modulus here else life would have been much easier 12 | 13 | lli C(int n, int r) //calculates nCr in O(r) time 14 | { 15 | lli z = 1; 16 | for(int i = 0; i < r; i++) 17 | z = z * (n-i)/(i+1); 18 | return z; 19 | } 20 | 21 | int main() 22 | { 23 | //no precomputation required 24 | int n, r; 25 | scanf("%d %d", &n , &r); 26 | lli ans = C(n, r); 27 | printf("(%dC%d) is %lld\n", n, r, ans); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /dp/kadaneIdx.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int kadane(int *a, int *start, int *end, int n) 5 | { 6 | int maxSum = INT_MIN, sum = 0; 7 | *end = -1; 8 | int local_start = 0; 9 | for(int i = 0; i < n; i++) 10 | { 11 | //sum = max(0, sum + a[i]); 12 | //maxSum = max(maxSum, sum); 13 | sum += a[i]; 14 | if(sum < 0) 15 | { 16 | sum = 0; 17 | local_start = i + 1; 18 | } 19 | else if(sum > maxSum) 20 | { 21 | maxSum = sum; 22 | *start = local_start; 23 | *end = i; 24 | } 25 | } 26 | if(*end != -1) 27 | return maxSum; 28 | } 29 | 30 | int main() 31 | { 32 | int start, end; 33 | int a[] = {-1, -2, -3}; 34 | int ans = kadane(a, &start, &end, 3 ); 35 | cout << ans << endl; 36 | cout << start << " " << end << endl; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /DataStructures/BIT/BIT1.c: -------------------------------------------------------------------------------- 1 | //Point Update, Range Sum Query Binary Indexed Tree 2 | //Author: Chandan Mittal 3 | #include 4 | 5 | int BIT[100010], n, a[100010]; 6 | 7 | void update(int x, int v) 8 | { 9 | while(x <= n) 10 | { 11 | BIT[x] += v; 12 | x += x & -x; 13 | } 14 | } 15 | 16 | int query(int k) 17 | { 18 | int s = 0; 19 | while(k > 0) 20 | { 21 | s += BIT[k]; 22 | k -= k & -k; 23 | } 24 | return s; 25 | } 26 | 27 | int main() 28 | { 29 | printf("Enter size of array>>"); 30 | scanf("%d",&n); 31 | int i, q, r; 32 | printf("Enter array elements\n"); 33 | for(i = 1 ; i <= n ; i++) 34 | { 35 | scanf("%d",&a[i]); 36 | update(i , a[i]); 37 | } 38 | printf("Enter range [x..y]>>"); 39 | scanf("%d %d",&q,&r); 40 | printf("sum of elements of range [%d..%d] is %d\n",q,r,query(r) - query(q-1)); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /dp/CoinChange.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define INF 1<<29 4 | /* 5 | given infinite supply of some denominations of coins, 6 | and a value V to be paid, tell 7 | the minimum number of coins needed to pay value V 8 | */ 9 | 10 | 11 | int CoinChange(int *coinValue, int n, int V) 12 | { 13 | int coins[V+1]; 14 | //coins[j] is the minimum no of coins needed to pay 'j' dollars 15 | fill(coins, coins + V+1, INF); 16 | 17 | coins[0] = 0; 18 | for(int i = 0; i < n; i++) 19 | for(int j = coinValue[i]; j <= V; j++) 20 | coins[j] = min(coins[j], 1 + coins[j - coinValue[i]]); 21 | 22 | return coins[V]; 23 | } 24 | 25 | int main() 26 | { 27 | int coinValue[] = {1, 2, 5, 10}; 28 | int value; 29 | cin >> value; 30 | int ans = CoinChange(coinValue, 4, value); 31 | cout << ans << endl; 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /DataStructures/BIT/BIT2.c: -------------------------------------------------------------------------------- 1 | //Point sum query, Range update Binary Indexed tree 2 | #include 3 | 4 | int BIT[10010], a[10010], n; 5 | 6 | int query(int k) 7 | { 8 | int s =0; 9 | while(k > 0) 10 | { 11 | s += BIT[k]; 12 | k -= k & -k; 13 | } 14 | return s; 15 | } 16 | 17 | void update(int x, int v) 18 | { 19 | while(x <= n) 20 | { 21 | BIT[x] += v; 22 | x += x & -x; 23 | } 24 | } 25 | 26 | 27 | int main() 28 | { 29 | scanf("%d",&n); 30 | int i, x, y, v; 31 | for(i = 1; i <= n ; i++) 32 | { 33 | scanf("%d",&a[i]); 34 | update(i, a[i]); 35 | update(i+1, -a[i]); 36 | } 37 | 38 | printf("Enter update query range[x..y]>>"); 39 | scanf("%d %d",&x, &y); 40 | printf("Enter value v to update by>>"); 41 | scanf("%d",&v); 42 | update(x, v); 43 | update(y+1, -v); 44 | for(i = x ; i <= y; i++) 45 | printf("updated %dth element is %d\n",i,query(i)); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /dp/Coin_ways.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAXV 100000 4 | /* 5 | Given n denominations of coins, tell 6 | the number of ways of paying any amount V, 7 | using different combinations of coin denominations 8 | Each query can be answered in O(1) after preprocessing 9 | 10 | */ 11 | 12 | long long ways[MAXV]; 13 | int Count_ways(int *coins, int n) 14 | { 15 | //ways[i] is number of ways of paying amount 'i 16 | 17 | fill(ways, ways + MAXV, 0); 18 | ways[0] = 1; //# of ways of paying 0 dollar is 1 19 | 20 | for(int i = 0; i < n; i++) 21 | for(int j = 0; j < MAXV; j++) 22 | if( j >= coins[i]) 23 | ways[j] += ways[j - coins[i]]; 24 | } 25 | 26 | int main() 27 | { 28 | int deno[] = {5, 10, 20, 50}; 29 | int n = sizeof(deno)/sizeof(int); 30 | Count_ways(deno, n); 31 | 32 | int value; 33 | cin >> value; 34 | cout << ways[value] << endl; 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /graph/DFS.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Depth First Search 3 | Time complexity: O(V + E) 4 | handle: calmhandtitan 5 | */ 6 | #include 7 | using namespace std; 8 | #define VI vector 9 | #define pb push_back 10 | #define SZ(v) (v).size() 11 | 12 | const int MAX = 1e5; // maximum no of nodes in a graph 13 | 14 | VI g[MAX]; 15 | bool vis[MAX]; 16 | int n, e; 17 | 18 | void dfs(int u) 19 | { 20 | vis[u] = 1; 21 | for(int i = 0; i < SZ(g[u]); i++) 22 | { 23 | int v = g[u][i]; 24 | if(!vis[v]) 25 | dfs(v); 26 | } 27 | } 28 | 29 | int main() 30 | { 31 | int x, y; 32 | scanf("%d %d",&n, &e); //get number of nodes and number of edges 33 | for(int i = 0; i < e; i++) 34 | { 35 | scanf("%d %d",&x, &y); 36 | x--,y--; 37 | g[x].pb(y); 38 | g[y].pb(x); //make undirected graph 39 | } 40 | 41 | for(int i = 0; i < n; i++) 42 | if(!vis[i]) //graph may be disconnected 43 | dfs(i); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /numberTheory/sieve_fast.cpp: -------------------------------------------------------------------------------- 1 | //sieves upto 10^8 in 0.5 sec, on core i5 CPU 2 | //Algo: Sieve of Eratosthenes using bitmasks 3 | #include 4 | #define i64 unsigned long long 5 | using namespace std; 6 | #define MAX 100000000 7 | #define LMT 10000 8 | 9 | unsigned flag[MAX/64]; 10 | unsigned primes[5761460], total; 11 | 12 | #define chkC(n) (flag[n>>6] & (1<<((n>>1)&31))) 13 | #define setC(n) (flag[n>>6] |= (1<<((n>>1)&31))) 14 | 15 | void sieve() 16 | { 17 | unsigned i, j, k; 18 | flag[0]|=0; 19 | for(i=3;i 2 | #define lli long long 3 | using namespace std; 4 | 5 | const int MOD = 1e9+7; 6 | const int MAX = 200010; 7 | 8 | lli mod_expo(lli a, lli b) 9 | { 10 | lli x = 1, y = a; 11 | while(b > 0) 12 | { 13 | if(b&1) x = (x*y)%MOD; 14 | y = (y*y)%MOD; 15 | b >>= 1; 16 | } 17 | return x; 18 | } 19 | 20 | lli fact[MAX], modFact[MAX]; 21 | 22 | void pre() //calculates nCr mod P where P is prime(1e9+7) and P>n, in O(n) time 23 | { 24 | fact[0] = 1; 25 | for(int i = 1 ; i <= MAX; i++) 26 | fact[i] = (i*fact[i-1])%MOD; 27 | 28 | 29 | modFact[0] = 1; 30 | 31 | for(int i = 1; i <= MAX; i++) 32 | modFact[i] = mod_expo(fact[i], MOD-2); 33 | } 34 | 35 | int main() 36 | { 37 | pre(); //do the MATH 38 | 39 | int n, r; 40 | scanf("%d %d", &n , &r); 41 | lli ans = fact[n]; 42 | ans = (ans*modFact[r])%MOD; 43 | ans = (ans*modFact[n-r])%MOD; 44 | printf("(%dC%d)%%%d is %lld\n", n, r,MOD, ans); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /numberTheory/modular_multiplicative_inverse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Modular Multiplicative Inverse 3 | compute MMI of a (mod m) 4 | Using Fermat't theorem: O(log(m)) 5 | Usig Euler's theorem: O(n) for n numbers 6 | */ 7 | #include 8 | #define VI vector 9 | #define lli long long 10 | using namespace std; 11 | 12 | lli modexpo(lli a, lli b, lli c) 13 | { 14 | lli x = 1, y = a; 15 | while(b > 0) 16 | { 17 | if(b&1) x = (x*y)%c; 18 | y = (y&y)%c; 19 | b >>= 1; 20 | } 21 | return x; 22 | } 23 | 24 | lli MMI(lli a, lli m) //computes MMI of a (mod m) in O(log(m)) time 25 | { 26 | return modexpo(a, m-2, m); //if m is prime, and gcd(a, m) = 1 27 | } 28 | 29 | VI inverseArray(lli n, lli m) //computes MMI of n numbers from 1 to n (mod m) in O(n) time 30 | { 31 | VI modInverse(n+1, 0); 32 | modInverse[1] = 1; 33 | for(int i = 2; i <= n; i++) 34 | { 35 | modInverse[i] = (-(m/i) * modInverse[m % i])%m + m; 36 | } 37 | return modInverse; 38 | } 39 | 40 | int main() 41 | { 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /numberTheory/LinearModularEquation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Linear Modular Equation 3 | Given a, b, c find x such that 4 | ax = b (mod c) and gcd(a, b, c) = 1 5 | 6 | then x = b*(a^phi(c)-1) (mod c) 7 | */ 8 | #include 9 | #define rep(i, x, n) for(size_t i = x, _n = n; i < _n; i++) 10 | #define lli long long 11 | using namespace std; 12 | 13 | lli modexpo(lli a, lli b, lli c) //computes a^b (mod c) in log2(b) time 14 | { 15 | lli x = 1, y = a; 16 | while(b > 0) 17 | { 18 | if(b&1) x = (x*y)%c; 19 | y = (y*y)%c; 20 | b >>= 1; 21 | } 22 | return x; 23 | } 24 | 25 | lli phi(lli n) 26 | { 27 | lli result = n; 28 | for(lli i = 2; i*i <= n; i++) 29 | { 30 | if(n%i == 0) 31 | { 32 | result -= result/i; 33 | while(n%i == 0) 34 | n /= i; 35 | } 36 | } 37 | if(n > 1) 38 | result -= result/n; 39 | return result; 40 | } 41 | 42 | int main() 43 | { 44 | lli a, b, c; 45 | cin >> a >> b >> c; 46 | lli fic = phi(c); 47 | lli x = modexpo(a, fic-1, c); 48 | x = (x*b)%c; 49 | cout << x << endl; 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /numberTheory/discreteLog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Discrete Logarithm 3 | Given a, b, m and gcd(a, m) = 1 4 | find solutions to a^x = b (mod m) 5 | 6 | Algo: Baby Step Giant Step, meet in the middle 7 | Complexity: O(root(m) * log(m)) 8 | Author: Chandan Mittal 9 | */ 10 | #include 11 | #define lli long long 12 | using namespace std; 13 | 14 | lli modexpo(lli a, lli b, lli m) 15 | { 16 | lli x = 1, y = a; 17 | while(b > 0) 18 | { 19 | if(b&1) 20 | x = (x * y) % m; 21 | y = (y * y) % m 22 | b >>= 1; 23 | } 24 | return x % m; 25 | } 26 | 27 | 28 | VI solve(lli a, lli b, lli m) 29 | { 30 | vector ans; 31 | lli n = (lli) sqrt(m + .0) + 1; 32 | map vals; 33 | 34 | for(lli p = n; p >= 1; --p) 35 | vals[ modexpo(a, n * p, m) ] = p; 36 | for(lli q = 0; q <= n; q++) 37 | { 38 | lli cur = (modexpo(a, q, m) * b) % m; 39 | if(vals.cout(cur)) 40 | { 41 | lli tmp = n * vals[cur] - q; 42 | if(tmp < m) 43 | ans.pb(tmp); 44 | } 45 | } 46 | return ans; 47 | } 48 | 49 | 50 | int main() 51 | { 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /numberTheory/modexpo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Modular Exponention 3 | https://en.wikipedia.org/wiki/Modular_exponentiation 4 | */ 5 | 6 | #include "bits/stdc++.h" 7 | #define sd(n) scanf("%d", &(n)) 8 | #define rep(i, x, n) for (size_t i = x, _n = (n); i < _n; ++i) 9 | #define SZ(c) (int)(c).size() 10 | #define lcm(a,b) (a*(b/__gcd(a,b))) 11 | #define VI vector 12 | #define all(c) ((c).begin(), (c).end()) 13 | #define pb push_back 14 | #define pii pair 15 | #define pip pair 16 | #define F first 17 | #define S second 18 | #define mp make_pair 19 | #define lli long long int 20 | #define CLR(p) memset(p, 0, sizeof(p)) 21 | #define SET(p) memset(p, -1, sizeof(p)) 22 | #define INF 0x3f3f3f3f 23 | using namespace std; 24 | 25 | const int MOD = 1e9+7; 26 | const int MAX = 100; 27 | 28 | lli modexpo(lli a, lli b) 29 | { 30 | lli x = 1, y = a; 31 | while(b > 0) 32 | { 33 | if(b&1) x = (x*y)%MOD; 34 | y = (y*y)%MOD; 35 | b >>= 1; 36 | } 37 | return x; 38 | } 39 | 40 | int main() 41 | { 42 | cout << modexpo(2, 16) << endl; //this prints (2^16) % MOD where MOD is 1e9+7 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /graph/BFS.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Breadth First Search 3 | Time complexity: O(V + E) 4 | handle: calmhandtitan 5 | */ 6 | #include 7 | using namespace std; 8 | #define VI vector< int > 9 | #define pb push_back 10 | #define SZ(v) (v).size() 11 | 12 | const int MAX = 1e5; //maximum no of nodes graph can have 13 | 14 | int n, e; 15 | bool vis[MAX]; 16 | VI g[MAX]; 17 | 18 | void bfs(int s) 19 | { 20 | vis[s] = 1; 21 | queue q; 22 | q.push(s); 23 | 24 | while(!q.empty()) 25 | { 26 | int u = q.front(); 27 | q.pop(); 28 | 29 | for(int i = 0; i < SZ(g[u]); i++) 30 | { 31 | int v = g[u][i]; 32 | if(!vis[v]) 33 | { 34 | vis[v] = 1; 35 | q.push(v); 36 | } 37 | } 38 | } 39 | } 40 | 41 | int main() 42 | { 43 | int x, y; 44 | scanf("%d %d", &n, &e); //get number of nodes and edges 45 | for(int i = 0; i < e; i++) 46 | { 47 | scanf("%d %d", &x, &y); //read edges 48 | x--, y--; 49 | g[x].pb(y); 50 | g[y].pb(x); //make undirected graph 51 | } 52 | for(int i = 0; i < n; i++) //graph may be disconnected 53 | if(!vis[i]) 54 | bfs(i); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /template.cpp: -------------------------------------------------------------------------------- 1 | //amazing takes time, legendary requires patience 2 | #include "bits/stdc++.h" 3 | #define sd(n) scanf("%d", &(n)) 4 | #define rep(i, x, n) for (int i = x, _n = (n); i < _n; ++i) 5 | #define repi(i, a) for(typeof((a).begin()) i = (a).begin(), _##i = (a).end(); i != _##i; ++i) 6 | #define SZ(c) (int)(c).size() 7 | #define pra(v, n) rep(i, 0, n) cout << v[i] << " "; cout << endl; 8 | #define lcm(a,b) (a*(b/__gcd(a,b))) 9 | #define VI vector 10 | #define all(c) (c).begin(), (c).end() 11 | #define pb push_back 12 | #define mii map 13 | #define pii pair 14 | #define pip pair 15 | #define F first 16 | #define S second 17 | #define mp make_pair 18 | #define lli long long int 19 | #define llu unsigned long long 20 | #define CLR(p) memset(p, 0, sizeof(p)) 21 | #define SET(p) memset(p, -1, sizeof(p)) 22 | #define INF 0x3f3f3f3f 23 | #define pi 3.14159265358979 24 | #define debug 0 25 | using namespace std; 26 | 27 | const int MOD = 1e9+7; 28 | const int eps = -1e6; 29 | const int MAX = 100010; 30 | 31 | 32 | int main() 33 | { 34 | ios_base::sync_with_stdio(0); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Chandan Mittal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /dp/catalanNumber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int CatalanNum_Recur(int n) //A O(4^n) naive algorithm 4 | { 5 | printf("n is %d\n",n); 6 | if(n == 0) 7 | return 1; 8 | int count = 0; 9 | for(int i = 1 ; i <= n ; i++) 10 | count += CatalanNum_Recur(i-1) * CatalanNum_Recur(n-i); 11 | 12 | return count; 13 | } 14 | 15 | const int MAX = 1024; 16 | int dp[MAX]; 17 | 18 | int CatalanNum_DP(int n) //A O(n^2) algorithm 19 | { 20 | printf("n is %d\n",n); 21 | // if(n == 1) 22 | // return 1; 23 | if(dp[n] != 1) 24 | return dp[n]; 25 | dp[n] = 0; 26 | for(int i = 1 ; i <= n ; i++) 27 | dp[n] += CatalanNum_DP(i - 1) * CatalanNum_DP(n - i); 28 | return dp[n]; 29 | } 30 | 31 | int main() 32 | { 33 | /* 34 | printf("Printing Catalan Number using Recursion\n"); 35 | for(int i = 1; i <= 50; i++) 36 | printf("%d ",CatalanNum_Recur(i)); 37 | printf("\n"); 38 | 39 | */ 40 | for(int i = 0; i < MAX; i++) 41 | dp[i] = 1; 42 | 43 | // for(int i = 0 ; i < 100 ; i++) 44 | // printf("%d ",dp[i]); 45 | // printf("\n"); 46 | 47 | // printf("Printing Catalan Number using DP\n"); 48 | // for(int i = 1; i <= 50; i++) 49 | // printf("%d ",CatalanNum_DP(i)); 50 | // printf("\n"); 51 | printf("Cat(2) is %d\n",CatalanNum_DP(2)); 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /dp/maxSumRectangle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAXROW 4 4 | #define MAXCOL 5 5 | 6 | int kadane(int *a, int n) 7 | { 8 | /* 9 | returns the maximum sum subArray 10 | Complexity: O(n) 11 | */ 12 | int max_ending_here = a[0], max_so_far = a[0]; 13 | for(int i = 0; i < n; i++) 14 | { 15 | max_ending_here = max(a[i], max_ending_here + a[i]); 16 | max_so_far = max(max_so_far, max_ending_here); 17 | } 18 | return max_so_far; 19 | } 20 | int M[MAXROW][MAXCOL]; 21 | 22 | int maxSumRect(int ROW, int COL) 23 | { 24 | /* 25 | returns the maximum Sum Rectangle in a 2-D Matrix M 26 | Complexity: O(n^3) 27 | */ 28 | int maxSum = 0; 29 | int temp[ROW]; 30 | for(int left = 0; left < COL; left++) 31 | { 32 | fill(temp, temp + ROW, 0); 33 | for(int right = left; right < COL; right++) 34 | { 35 | for(int i = 0; i < ROW; i++) 36 | temp[i] += M[i][right]; 37 | 38 | int sum = kadane(temp, ROW); 39 | maxSum = max(sum, maxSum); 40 | } 41 | } 42 | return maxSum; 43 | } 44 | 45 | int main() 46 | { 47 | int ROW = 4, COL = 5; 48 | for(int i = 0; i < ROW; i++) 49 | for(int j = 0; j < COL; j++) 50 | scanf("%d ", &M[i][j]); 51 | int ans = maxSumRect(ROW, COL); 52 | printf("%d\n", ans); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /stringTheory/KMP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX 10001 4 | int F[MAX]; 5 | 6 | void compute_Prefix(char P[], int m) 7 | { 8 | int i = 1, j = 0; 9 | F[0] = 0; 10 | while(i < m) 11 | { 12 | if(P[i] == P[j]) 13 | { 14 | F[i] = j + 1; 15 | i++; 16 | j++; 17 | } 18 | else if(j > 0) 19 | j = F[j-1]; 20 | else 21 | { 22 | F[i] = 0; 23 | i++; 24 | } 25 | } 26 | } 27 | 28 | int KMP(char T[], int n, char P[], int m) 29 | { 30 | int i = 0, j = 0; 31 | compute_Prefix(P, m); 32 | while(i < n) 33 | { 34 | if(T[i] == P[j]) 35 | { 36 | if(j == m-1) //successfull match 37 | return i-j; 38 | else 39 | i++, j++; 40 | } 41 | else if(j > 0) 42 | j = F[j-1]; 43 | else 44 | i++; 45 | } 46 | return -1; 47 | } 48 | 49 | int main() 50 | { 51 | char text[MAX], pattern[MAX]; 52 | 53 | printf("Enter the text to search pattern in>>"); 54 | scanf("%s", text); 55 | printf("Enter the pattern to search for>>"); 56 | scanf("%s", pattern); 57 | 58 | int n = strlen(text); 59 | int m = strlen(pattern); 60 | 61 | int ans = KMP(text, n, pattern, m); 62 | 63 | if(ans == -1) 64 | printf("pattern not found\n"); 65 | else 66 | printf("pattern found at index %d\n", ans); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /graph/cycleDetection_undirectedGraph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define sd(n) scanf("%d", &(n)); 3 | #define SZ(s) (int)(s.size()) 4 | #define rep(i, x, n) for(int i = x, _n = n; i < _n; i++) 5 | #define VI vector 6 | #define pb push_back 7 | using namespace std; 8 | 9 | const int MAX = 1010; 10 | 11 | vector< VI > g; 12 | bool visited[MAX], hasCycle; 13 | int n, e; 14 | 15 | void dfs(int v, int parent) 16 | { 17 | visited[v] = 1; 18 | 19 | rep(i, 0, SZ(g[v])) 20 | { 21 | if(!visited[g[v][i]]) 22 | dfs(g[v][i], v); 23 | else if(g[v][i] != parent) //if we see a visited node other than cur node's parent 24 | { 25 | hasCycle = true; 26 | return; 27 | } 28 | } 29 | } 30 | 31 | 32 | int main() 33 | { 34 | sd(n); //get number of nodes 35 | sd(e); //get number of edges 36 | 37 | g = vector< VI > (n); 38 | 39 | int u, v; 40 | rep(i, 0, e) 41 | { 42 | sd(u); 43 | sd(v); 44 | u--, v--; //it is assumed that nodes entered are 1-based indexed 45 | g[u].pb(v); 46 | g[v].pb(u); 47 | } 48 | 49 | rep(i, 0, n) 50 | { 51 | if(!visited[i]) 52 | { 53 | dfs(i, -1); 54 | if(hasCycle) 55 | break; 56 | } 57 | } 58 | 59 | if(hasCycle) 60 | printf("given undirected graph HAS A CYCLE\n"); 61 | else 62 | printf("given undirected graph DOES NOT have any cycle\n"); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /dp/LCS_spaceOptimized.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Longest Common Subsequence of 2 strings 3 | */ 4 | 5 | #include "bits/stdc++.h" 6 | #define sd(n) scanf("%d", &(n)) 7 | #define rep(i, x, n) for (size_t i = x, _n = (n); i < _n; ++i) 8 | #define SZ(c) (int)(c).size() 9 | #define lcm(a,b) (a*(b/__gcd(a,b))) 10 | #define VI vector 11 | #define all(c) ((c).begin(), (c).end()) 12 | #define pb push_back 13 | #define pii pair 14 | #define pip pair 15 | #define F first 16 | #define S second 17 | #define mp make_pair 18 | #define lli long long int 19 | #define CLR(p) memset(p, 0, sizeof(p)) 20 | #define SET(p) memset(p, -1, sizeof(p)) 21 | #define INF 0x3f3f3f3f 22 | using namespace std; 23 | 24 | const int MOD = 1e9+7; 25 | const int MAX = 100010; 26 | 27 | int dp[2][MAX]; //space required is 2 x N only 28 | 29 | int LCS(string a, string b) //an O(n^2) implementation 30 | { 31 | int n = SZ(a); 32 | int m = SZ(b); 33 | 34 | int k = 1; 35 | 36 | for(int i = 1; i <= n; i++) 37 | { 38 | for(int j = 1; j <= m; j++) 39 | { 40 | if(a[i-1] == b[j-1]) 41 | dp[k][j] = 1 + dp[1-k][j-1]; 42 | else 43 | dp[k][j] = max(dp[1-k][j], dp[k][j-1]); 44 | } 45 | k = 1 - k; 46 | } 47 | return dp[1-k][m]; 48 | } 49 | 50 | int main() 51 | { 52 | string a = "abcdef", b = "bde"; 53 | cout << LCS(a, b) << endl; 54 | return 0; 55 | } 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /DataStructures/Union_Find.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX 10010 4 | 5 | class Union_Find 6 | { 7 | int parent[MAX], sz[MAX]; 8 | public: 9 | Union_Find(int n) 10 | { 11 | for(int i = 0; i <= n; i++) 12 | { 13 | parent[i] = i; 14 | sz[i] = 1; 15 | } 16 | } 17 | 18 | int root(int i) 19 | { 20 | while(i != parent[i]) 21 | { 22 | parent[i] = parent[parent[i]]; 23 | i = parent[i]; 24 | } 25 | return i; 26 | } 27 | 28 | int find(int p, int q) 29 | { 30 | return root(p) == root(q); 31 | } 32 | 33 | int unite(int p, int q) 34 | { 35 | int i = root(p); 36 | int j = root(q); 37 | 38 | if(sz[i] < sz[j]) 39 | { 40 | parent[i] = parent[j]; 41 | sz[j] += sz[i]; 42 | } 43 | else 44 | { 45 | parent[j] = parent[i]; 46 | sz[i] += sz[j]; 47 | } 48 | } 49 | int getNumberOfCompo(int n) //returns the number of disjoint sets 50 | { 51 | set s; 52 | for(int i = 1; i <= n; i++) //assuming 1 based index 53 | { 54 | s.insert(root(i)); 55 | } 56 | return s.size(); 57 | } 58 | }; 59 | 60 | 61 | int main() 62 | { 63 | int n, e, x, y; 64 | cin >> n >> e; 65 | Union_Find UF(n); 66 | for(int i = 0 ; i < e; i++) 67 | { 68 | cin >> x >> y; 69 | if(!UF.find(x, y)) 70 | UF.unite(x, y); 71 | } 72 | cout << UF.getNumberOfCompo(n) << endl; 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /DataStructures/stack/Histogram.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int Histogram(int *histo, int n) 5 | { 6 | stack heights, index; 7 | int largestArea = 0; 8 | 9 | for(int i = 0; i < n; i++) 10 | { 11 | //case 1. current height is larger than that at TOS 12 | if(heights.empty() || histo[i] > heights.top()) //or of stack is empty 13 | { 14 | heights.push(histo[i]); 15 | index.push(i); 16 | } 17 | //case 2. current height is less than that at TOS 18 | else if(histo[i] < heights.top()) 19 | { 20 | int lastIndex = 0; 21 | //if the current height is shorter, we need to pop those longer heights 22 | //and compute the current rectangle area 23 | while(!heights.empty() && histo[i] < heights.top()) 24 | { 25 | //compute current area 26 | lastIndex = index.top(); 27 | int tempArea = heights.top() * (i - lastIndex); 28 | heights.pop(), index.pop(); 29 | largestArea = max(tempArea, largestArea); 30 | } 31 | heights.push(histo[i]); 32 | index.push(lastIndex); 33 | } 34 | } 35 | while(!heights.empty()) 36 | { 37 | int tempArea = heights.top() * (n - index.top() ); 38 | heights.pop(), index.pop(); 39 | largestArea = max(largestArea, tempArea); 40 | } 41 | return largestArea; 42 | } 43 | 44 | int main() 45 | { 46 | int h[] = {2, 4, 2, 1}; 47 | int ans = Histogram(h, 4); 48 | cout << ans << endl; 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /graph/cycleDetection_directedGraph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define sd(n) scanf("%d", &(n)); 3 | #define SZ(s) (int)(s.size()) 4 | #define rep(i, x, n) for(int i = x, _n = n; i < _n; i++) 5 | #define VI vector 6 | #define pb push_back 7 | using namespace std; 8 | 9 | const int MAX = 1010; 10 | 11 | vector< VI > g; 12 | bool visited[MAX], used[MAX], hasCycle; 13 | int n, e; 14 | 15 | void dfs(int v) 16 | { 17 | visited[v] = used[v] = 1; //push node v in recursion stack 18 | 19 | rep(i, 0, SZ(g[v])) 20 | { 21 | if(used[g[v][i]]) //if we encounter a node which is already in stack 22 | { 23 | hasCycle = 1; 24 | return; 25 | } 26 | else if(!visited[g[v][i]]); 27 | dfs(g[v][i]); 28 | } 29 | used[v] = 0; //pop node v from stack as it's DFS is over 30 | } 31 | 32 | 33 | int main() 34 | { 35 | sd(n); //get number of nodes 36 | sd(e); //get number of edges 37 | 38 | g = vector< VI > (n); 39 | 40 | int u, v; 41 | rep(i, 0, e) 42 | { 43 | sd(u); 44 | sd(v); 45 | u--, v--; //it is assumed that nodes entered are 1-based indexed 46 | g[u].pb(v); //directed graph it is 47 | } 48 | 49 | rep(i, 0, n) 50 | { 51 | if(!visited[i]) 52 | { 53 | dfs(i); 54 | if(hasCycle) 55 | break; 56 | } 57 | } 58 | 59 | if(hasCycle) 60 | printf("given directed graph HAS A CYCLE\n"); 61 | else 62 | printf("given directed graph DOES NOT have any cycle\n"); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /dp/LCS.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Longest Common Subsequence of 2 strings 3 | */ 4 | 5 | #include "bits/stdc++.h" 6 | #define sd(n) scanf("%d", &(n)) 7 | #define rep(i, x, n) for (size_t i = x, _n = (n); i < _n; ++i) 8 | #define SZ(c) (int)(c).size() 9 | #define lcm(a,b) (a*(b/__gcd(a,b))) 10 | #define VI vector 11 | #define all(c) ((c).begin(), (c).end()) 12 | #define pb push_back 13 | #define pii pair 14 | #define pip pair 15 | #define F first 16 | #define S second 17 | #define mp make_pair 18 | #define lli long long int 19 | #define CLR(p) memset(p, 0, sizeof(p)) 20 | #define SET(p) memset(p, -1, sizeof(p)) 21 | #define INF 0x3f3f3f3f 22 | using namespace std; 23 | 24 | const int MOD = 1e9+7; 25 | const int MAX = 100010; 26 | 27 | int LCS(string a, string b) //O(n^2) implementation of LCS 28 | { 29 | int m = a.size(), n = b.size(); 30 | int dp[m+1][n+1]; 31 | 32 | for (int i = 0; i <= m; ++i) 33 | { 34 | for (int j = 0; j <= n; ++j) 35 | { 36 | if(i == 0 || j == 0) 37 | dp[i][j] = 0; 38 | else if(a[i-1] == b[j-1]) 39 | dp[i][j] = dp[i-1][j-1] + 1; 40 | else 41 | dp[i][j] = max(dp[i-1][j], dp[i][j-1]); 42 | } 43 | } 44 | return dp[m][n]; 45 | 46 | } 47 | 48 | int main() 49 | { 50 | string a = "abcdef", b = "bde"; 51 | cout << LCS(a, b) << endl; 52 | return 0; 53 | } 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /linearAlgebra/gaussian_elimination.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Gaussian Elimination 3 | Time Complexity: O(n^3) 4 | handle: calmhandtitan 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | const int MAX = 110; 10 | 11 | int n; 12 | double a[MAX][MAX]; 13 | double x[MAX]; 14 | 15 | void read_matrix() 16 | { 17 | scanf("%d", &n); //get the size of the matrix N x N 18 | 19 | for(int i = 1; i <= n; i++) 20 | { 21 | for(int j = 1; j <= (n+1); j++) //note the indexing is 1-based 22 | scanf("%lf", &a[i][j]); //read the augmented matrix 23 | } 24 | } 25 | 26 | void gauss_elim() // complexity: O(n^3) 27 | { 28 | //generating upper triangular matrix 29 | for(int j = 1; j <= n ; j++) 30 | { 31 | for(int i = 1; i <= n; i++) 32 | { 33 | if(i > j) 34 | { 35 | double c = a[i][j] / a[j][j]; 36 | for(int k = 1; k <= n+1; k++) 37 | a[i][k] = a[i][k] - c*a[j][k]; 38 | } 39 | } 40 | } 41 | 42 | //now doing backward substitution 43 | x[n] = a[n][n+1] / a[n][n]; 44 | 45 | double sum = 0.0; 46 | 47 | for(int i = n-1; i >= 1; --i) 48 | { 49 | sum = 0; 50 | 51 | for(int j = i+1; j <= n; j++) 52 | { 53 | sum += a[i][j] * x[j]; 54 | } 55 | x[i] = (a[i][n+1] - sum) / a[i][i]; 56 | } 57 | 58 | printf("soln is: \n"); 59 | for(int i = 1; i <= n; i++) 60 | { 61 | printf("x%d = %lf\n", i, x[i]); 62 | } 63 | 64 | } 65 | 66 | int main() 67 | { 68 | read_matrix(); 69 | gauss_elim(); 70 | } 71 | -------------------------------------------------------------------------------- /graph/bridges.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define rep(i, x, n) for(int i = x, _n = n; i < _n; i++) 3 | #define sd(n) scanf("%d", &n) 4 | #define VI vector 5 | #define pb push_back 6 | #define SET(n) memset(n, -1, sizeof(n)) 7 | #define CLR(n) memset(n, 0, sizeof(n)) 8 | using namespace std; 9 | 10 | const int MAX = 100010; 11 | int n, e; 12 | vector graph; 13 | int low[MAX], arrTime[MAX], parent[MAX]; 14 | bool visited[MAX]; 15 | 16 | void bridge(int u) 17 | { 18 | static int time = 0; 19 | visited[u] = 1; 20 | 21 | arrTime[u] = low[u] = time++; 22 | 23 | for(VI::iterator it = graph[u].begin(); it != graph[u].end(); it++) 24 | { 25 | int v = *it; //v is adjacent to u 26 | 27 | if(!visited[v]) 28 | { 29 | parent[v] = u; 30 | bridge(v); 31 | 32 | low[u] = min(low[u], low[v]); 33 | 34 | if(low[v] > arrTime[u]) //u, v is bridge edge 35 | { 36 | cout << u << " -> " << v << " is a bridge\n"; 37 | } 38 | } 39 | else if(v != parent[u]) 40 | low[u] = min(low[u], arrTime[v]); 41 | } 42 | } 43 | 44 | int main() 45 | { 46 | sd(n); //get number of nodes 47 | sd(e); //get number of edges 48 | graph = vector (n); //initialize graph 49 | 50 | int x, y; 51 | rep(i, 0, e) 52 | { 53 | sd(x); 54 | sd(y); 55 | //it is assumed that nodes are indexed from 0 56 | graph[x].pb(y); 57 | graph[y].pb(x); 58 | } 59 | 60 | //clear the required arrays 61 | CLR(arrTime); 62 | CLR(low); 63 | CLR(visited); 64 | SET(parent); 65 | 66 | bridge(0); //call the bridge procedure 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /graph/flloydWarshall.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | All pair shortest path 3 | Flloyd Warshall Algorithm 4 | Time Complexity: O(V^3) 5 | 6 | NOTE: works for both positive and negative edge wwights, 7 | but fails for negative cycles 8 | 9 | */ 10 | #include 11 | using namespace std; 12 | 13 | const int MAX = 210; 14 | const int INF = 1<<20; 15 | 16 | int dist[MAX][MAX]; //dist matrix is n*n matrix 17 | int n, e; //n is no of nodes, e is no of edges 18 | 19 | 20 | void init() 21 | { 22 | for(int i = 0; i < n; i++) 23 | for(int j = 0; j < n; j++) 24 | if(i == j) 25 | dist[i][j] = 0; //since there can't be self loops 26 | else 27 | dist[i][j] = INF; //set all distances to INF 28 | } 29 | 30 | void fWarshall() 31 | { 32 | for(int k = 0; k < n; k++) 33 | for(int i = 0; i < n; i++) 34 | for(int j = 0; j < n; j++) 35 | dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]); 36 | 37 | } 38 | 39 | void view() 40 | { 41 | for(int i = 0; i < n; i++) 42 | { 43 | for(int j = 0; j < n; j++) 44 | if(dist[i][j] == INF) 45 | printf("INF\t"); 46 | else 47 | printf("%d\t", dist[i][j]); 48 | printf("\n"); 49 | } 50 | } 51 | 52 | 53 | int main() 54 | { 55 | scanf("%d %d", &n, &e); 56 | 57 | init(); //initialize distance matrix 58 | 59 | int u, v, wt; 60 | for(int i = 0; i < e; i++) 61 | { 62 | scanf("%d %d %d", &u, &v, &wt); 63 | u--, v--; //it is assumed that input nodes are 1-based indexed 64 | dist[u][v] = wt; 65 | } 66 | 67 | fWarshall(); //run flloydWarshall that takes O(n^3) time 68 | 69 | view(); 70 | 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /computational geometry/closest point pair.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Closest point pair problem 3 | Algo: Line sweep algorithm 4 | Complexity: O(NlogN) 5 | handle: calmhandtitan 6 | */ 7 | #include 8 | using namespace std; 9 | #define lli long long int 10 | #define py first 11 | #define px second 12 | #define mp make_pair 13 | #define debug 0 14 | 15 | const int MAX = 1e5; 16 | const lli INF = 1LL<<60; 17 | 18 | typedef pair point; 19 | point p[MAX]; //p[i] is y, x; see macro defined 20 | set s; 21 | map mapp; 22 | int n; 23 | double best; 24 | 25 | bool cmp(point a, point b) { return a.px < b.px; } 26 | 27 | int main() 28 | { 29 | scanf("%d", &n); 30 | for(int i = 0; i < n; i++) 31 | { 32 | scanf("%lld %lld", &p[i].px, &p[i].py); //assuming all points are integral coordinates 33 | mapp[p[i]] = i; //since all the point are unique 34 | } 35 | sort(p, p+n, cmp); //sort in increasing order of x coordinate 36 | best = INF; //let minimum dist be INF 37 | s.insert(p[0]); //this is the active set 38 | int left = 0, pos1, pos2; 39 | for(int i = 1; i < n; i++) 40 | { 41 | while(left < i and p[i].px - p[left].px > best) s.erase(p[left++]); 42 | for(typeof(s.begin()) it = s.lower_bound(mp(p[i].py - best, p[i].px - best)); it != s.end() and p[i].py + best >= it->py; it++) 43 | { 44 | double d = sqrt(pow(p[i].py - it->py, 2.0) + pow(p[i].px - it->px, 2.0)); 45 | if(d < best) 46 | { 47 | best = d; 48 | pos1 = mapp[p[i]], pos2 = mapp[*it]; 49 | } 50 | } 51 | s.insert(p[i]); 52 | } 53 | if(pos1 > pos2) swap(pos1, pos2); 54 | printf("%d %d %.6lf\n", pos1, pos2, best); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /graph/checkEuler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check if an undirected graph has eulerian cycle or not 3 | Complexity: O(n) 4 | handle: calmhandtitan 5 | */ 6 | #include "bits/stdc++.h" 7 | #define sd(n) scanf("%d", &(n)) 8 | #define rep(i, x, n) for (int i = x, _n = (n); i < _n; ++i) 9 | #define repi(i, a) for(typeof((a).begin()) i = (a).begin(), _##i = (a).end(); i != _##i; ++i) 10 | #define pra(v) repi(it, v) cout << *it << " "; cout << endl; 11 | #define SZ(c) (int)(c).size() 12 | #define lcm(a,b) (a*(b/__gcd(a,b))) 13 | #define VI vector 14 | #define all(c) (c).begin(), (c).end() 15 | #define allr(c) (c).rbegin(), (c).rend() 16 | #define pb push_back 17 | #define mii map 18 | #define pii pair 19 | #define pip pair 20 | #define F first 21 | #define S second 22 | #define mp make_pair 23 | #define lli long long int 24 | #define llu unsigned long long 25 | #define CLR(p) memset(p, 0, sizeof(p)) 26 | #define SET(p) memset(p, -1, sizeof(p)) 27 | #define INF 0x3f3f3f3f 28 | #define pi 3.141592653589793 29 | #define debug 0 30 | using namespace std; 31 | 32 | const int MOD = 1e9+7; 33 | const int MAX = 100010; 34 | const double eps = -1e8; 35 | 36 | int n, m, x, y, deg[MAX], odd; 37 | 38 | int main() 39 | { 40 | ios_base::sync_with_stdio(0); 41 | sd(n); 42 | sd(m); 43 | rep(i, 0, m) 44 | { 45 | sd(x); 46 | sd(y); 47 | x--, y--; 48 | deg[x]++, deg[y]++; 49 | } 50 | rep(i, 0, n) 51 | if(deg[i]&1) odd++; 52 | if(odd == 0) 53 | printf("Graph has Euler cycle(s)\n"); 54 | else if(odd == 2) 55 | printf("Graph has Eulerian path(s) but no euler cycle\n"); 56 | else 57 | printf("Graph is not Eulerian\n"); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /numberTheory/matrix_expo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define rep(i, x, n) for(size_t i = x, _n = n; i < _n; i++) 3 | #define lli long long 4 | using namespace std; 5 | 6 | typedef vector< lli > row; 7 | typedef vector< row > matrix; 8 | 9 | const int MOD = 1e9+7; 10 | 11 | void clear(matrix &A) //clears a matrix in O(n^2) time 12 | { 13 | rep(i, 0, A.size()) 14 | rep(j, 0, A.size()) 15 | A[i][j] = 0; 16 | } 17 | 18 | matrix mul(const matrix &A, const matrix &B) //multiplies 2 matrices in O(n^3) time 19 | { 20 | matrix C = A; 21 | clear(C); 22 | rep(i, 0, C.size()) 23 | rep(j, 0, C[i].size()) 24 | rep(k, 0, A.size()) 25 | C[i][j] = (C[i][j] + A[i][k] * B[k][j])%MOD; 26 | return C; 27 | } 28 | 29 | matrix pow(matrix &A, lli p) //computes matrix A to the power p in O(log(p)) time 30 | { 31 | if(p == 0) 32 | { 33 | matrix C = A; 34 | clear(C); 35 | rep(i, 0, C.size()) 36 | C[i][i] = 1; 37 | return C; 38 | } 39 | matrix C = pow(A, p/2); 40 | C = mul(C, C); 41 | if(p&1) 42 | C = mul(C, A); 43 | return C; 44 | } 45 | 46 | //solves matrix expo for recurrence f(N) = f(N-x1) + f(N-x2) + ... 47 | void solve() 48 | { 49 | lli N; 50 | cin >> N; 51 | const int matrix_size = 16; 52 | matrix A = matrix(matrix_size, row(matrix_size, 0)); 53 | 54 | rep(i, 1, A.size()) 55 | A[i][i - 1] = 1; 56 | 57 | int k, x; 58 | cin >> k; 59 | rep(i, 0, k) 60 | { 61 | cin >> x; //f(N) = f(N-x1) + f(N-x2) + ... 62 | A[0][x - 1] = 1; 63 | } 64 | 65 | matrix B = pow(A, N); //compute matrix A to power L 66 | cout << B[0][0] << endl;//prints N+1'th term of sequence 67 | } 68 | 69 | int main() 70 | { 71 | int t; 72 | cin >> t; 73 | while(t--) 74 | { 75 | solve(); 76 | } 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /DataStructures/BIT/inversion_count.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Inversion Count 3 | Algo: Binary Indexed Tree 4 | Time Complexity: O(NlogN) 5 | handle: calmhandtitan 6 | */ 7 | #include "bits/stdc++.h" 8 | #define sd(n) scanf("%d", &(n)) 9 | #define rep(i, x, n) for (int i = x, _n = (n); i < _n; ++i) 10 | #define repi(i, a) for(typeof((a).begin()) i = (a).begin(), _##i = (a).end(); i != _##i; ++i) 11 | #define SZ(c) (int)(c).size() 12 | #define lcm(a,b) (a*(b/__gcd(a,b))) 13 | #define VI vector 14 | #define all(c) (c).begin(), (c).end() 15 | #define pb push_back 16 | #define mii map 17 | #define pii pair 18 | #define pip pair 19 | #define F first 20 | #define S second 21 | #define mp make_pair 22 | #define lli long long int 23 | #define CLR(p) memset(p, 0, sizeof(p)) 24 | #define SET(p) memset(p, -1, sizeof(p)) 25 | #define INF 0x3f3f3f3f 26 | #define pi 3.14159265358979 27 | #define debug 0 28 | using namespace std; 29 | 30 | const int MOD = 1e9+7; 31 | const int MAX = 100010; 32 | 33 | int n, a[MAX], b[MAX]; 34 | lli BIT[MAX]; 35 | 36 | void update(int x, int v) 37 | { 38 | while(x <= n) 39 | { 40 | BIT[x] += v; 41 | x += x & (-x); 42 | } 43 | } 44 | 45 | lli read(int x) 46 | { 47 | lli s = 0; 48 | while(x > 0) 49 | { 50 | s += BIT[x]; 51 | x -= x & (-x); 52 | } 53 | return s; 54 | } 55 | 56 | int main() 57 | { 58 | ios_base::sync_with_stdio(0); 59 | sd(n); 60 | 61 | rep(i, 0, n) 62 | { 63 | sd(a[i]); 64 | b[i] = a[i]; 65 | } 66 | sort(b, b+n); 67 | rep(i, 0, n) 68 | { 69 | int id = lower_bound(b, b+n, a[i]) - b; 70 | a[i] = id+1; 71 | } 72 | CLR(BIT); 73 | lli ans = 0; 74 | for(int i = n-1; i >= 0; --i) 75 | { 76 | ans += read(a[i]-1); 77 | update(a[i], 1); 78 | } 79 | printf("%d\n", ans); 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /DataStructures/sparse table/1D_RMQ.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 1D Range minimum query using Sparse table 3 | Time Complexity: 4 | Space Complexity: O(NLogN) 5 | */ 6 | #include "bits/stdc++.h" 7 | using namespace std; 8 | 9 | const int MOD = 1e9+7; 10 | const int MAX = 100010; 11 | 12 | int a[MAX]; 13 | int table[1<<20][20]; /* table[i][j] is the index of minimum value in sub array starting at i having length 2^j */ 14 | 15 | int main() 16 | { 17 | int t, n, q, x, y; 18 | scanf("%d", &t); 19 | while(t--) 20 | { 21 | scanf("%d", &n); 22 | scanf("%d", &q); 23 | for(int i = 0; i < n; i++) 24 | scanf("%d", &a[i]); 25 | 26 | /* initialize table for interval with length 1 */ 27 | for(int i = 0; i < n; i++) 28 | table[i][0] = i; 29 | /* compute values from smaller to bigger intervals */ 30 | for(int j = 1; (1< 2 | using namespace std; 3 | #define pii pair< int, int> 4 | #define pb push_back 5 | #define INF (1<<20) 6 | #define MAX 100001 7 | 8 | vector< vector > graph; 9 | int nodes, edges; 10 | int dist[MAX]; 11 | bool Finish[MAX]; 12 | 13 | void Dijikstra(int src) 14 | { 15 | for(int i = 1; i <= nodes; i++) 16 | dist[i] = INF; 17 | dist[src] = 0; 18 | 19 | priority_queue< pii, vector< pii>, greater > PQ; 20 | PQ.push(pii(0, src)); 21 | int v, w; 22 | 23 | while(!PQ.empty()) 24 | { 25 | int u = (PQ.top()).second; 26 | PQ.pop(); 27 | 28 | if(Finish[u]) 29 | continue; 30 | 31 | int sz = graph[u].size(); 32 | 33 | for(int i = 0; i < sz; i++) 34 | { 35 | v = graph[u][i].first; 36 | w = graph[u][i].second; 37 | 38 | if(!Finish[v] && dist[u] + w < dist[v]) 39 | { 40 | dist[v] = dist[u] + w; 41 | PQ.push(pii(dist[v], v)); 42 | } 43 | 44 | } 45 | Finish[u] = 1; 46 | 47 | } 48 | } 49 | 50 | void view() 51 | { 52 | for(int i = 0; i < nodes; i++) 53 | { 54 | for(int j = 0; j < graph[i].size(); j++) 55 | { 56 | printf("%d --- %d --->> %d\n",i, graph[i][j].second, graph[i][j].first); 57 | } 58 | } 59 | } 60 | 61 | int main() 62 | { 63 | int x, y, wt, source; 64 | scanf("%d %d",&nodes, &edges); 65 | 66 | graph = vector< vector< pii > > (nodes+1); //initialize n+1 nodes in graph 67 | 68 | for(int i = 0; i < edges; i++) 69 | { 70 | scanf("%d %d %d",&x, &y, &wt); 71 | graph[x].pb( pii(y, wt) ); 72 | // graph[y].pb( pii(x, wt) ); //for undirected graphs 73 | } 74 | // view(); 75 | scanf("%d",&source); 76 | Dijikstra(source); 77 | 78 | printf("From %d to:\n", source); 79 | for(int i = 1; i <= nodes; i++) 80 | printf("Node = %d, min_weight_path = %d\n",i, dist[i]); 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /DataStructures/segmentTree/rangeSumSegmentTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int *st; 5 | 6 | int query(int *st, int start, int end, int qs, int qe, int idx) 7 | { 8 | if(qs <= start && qe >= end) 9 | return st[idx]; 10 | 11 | if(end < qs || start > qe) 12 | return 0; 13 | 14 | int mid = (start+end)/2; 15 | return query(st, start, mid, qs, qe, 2*idx+1) + 16 | query(st, mid+1, end, qs, qe, 2*idx+2); 17 | } 18 | 19 | void updateIt(int *st, int start, int end, int pos, int diff, int idx) 20 | { 21 | if(pos < start || pos > end) 22 | return; 23 | 24 | st[idx] += diff; 25 | if(start != end) 26 | { 27 | int mid = (start+end)/2; 28 | updateIt(st, start, mid, pos, diff, 2*idx+1); 29 | updateIt(st, mid+1, end, pos, diff, 2*idx+2); 30 | } 31 | } 32 | 33 | void update(int a[], int n, int *st, int pos, int new_val) 34 | { 35 | int diff = new_val - a[pos]; 36 | a[pos] = new_val; 37 | 38 | updateIt(st, 0, n-1, pos, diff, 0); 39 | } 40 | 41 | int build(int a[], int start, int end, int *st, int idx) 42 | { 43 | if(start == end) 44 | { 45 | st[idx] = a[start]; 46 | return st[idx]; 47 | } 48 | 49 | int mid = (start+end)/2; 50 | st[idx] = build(a, start, mid, st, 2*idx+1) + 51 | build(a, mid+1, end, st, 2*idx+2); 52 | return st[idx]; 53 | } 54 | 55 | void init(int a[], int n) 56 | { 57 | int x = (int)ceil(log2(n)); 58 | int max_size = 2*(int)pow(2, x) - 1; 59 | 60 | st = (int*)malloc(sizeof(int)*max_size); 61 | build(a, 0, n-1, st, 0); 62 | } 63 | 64 | int main() 65 | { 66 | int a[] = {1, 2, 3, 4, 5}; 67 | int n = sizeof(a)/sizeof(a[0]); 68 | 69 | init(a, n); 70 | cout << query(st, 0, n-1, 0, 2, 0) << endl;//query sum from a[0]-a[2] 71 | update(a, n, st, 2, 5); //update a[2] -> 5 72 | cout << query(st, 0, n-1, 1, 3, 0) << endl;//query sum from a[1]-a[3] 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /dp/LIS_LDS_BTS.cpp: -------------------------------------------------------------------------------- 1 | //amazing takes time, legendary requires patience 2 | #include "bits/stdc++.h" 3 | #define sd(n) scanf("%d", &(n)) 4 | #define rep(i, x, n) for (int i = x, _n = (n); i < _n; ++i) 5 | #define repV(i, v) for (i = v.begin(); i != v.end(); i++) 6 | #define SZ(c) (int)(c).size() 7 | #define lcm(a,b) (a*(b/__gcd(a,b))) 8 | #define VI vector 9 | #define all(c) (c).begin(), (c).end() 10 | #define pb push_back 11 | #define mii map 12 | #define pii pair 13 | #define pip pair 14 | #define F first 15 | #define S second 16 | #define mp make_pair 17 | #define lli long long int 18 | #define CLR(p) memset(p, 0, sizeof(p)) 19 | #define SET(p) memset(p, -1, sizeof(p)) 20 | #define INF 0x3f3f3f3f 21 | #define pi 3.14159265358979 22 | using namespace std; 23 | 24 | const int MOD = 1e9+7; 25 | const int MAX = 1010; 26 | 27 | int a[MAX], dp1[MAX], dp2[MAX]; 28 | //dp1[i] is the longest increasing subsequence till index i 29 | //dp2[i] is the longest decreasing subsequence till index i 30 | int n; 31 | 32 | int main() 33 | { 34 | ios_base::sync_with_stdio(0); 35 | int t; 36 | sd(t); 37 | while(t--) 38 | { 39 | sd(n); 40 | rep(i, 1, n+1) 41 | sd(a[i]); 42 | 43 | rep(i, 1, n+1) 44 | dp1[i] = dp2[i] = 1; 45 | 46 | rep(i, 1, n+1) 47 | rep(j, i+1, n+1) 48 | if(a[j] > a[i]) //note it is strictly increasing 49 | dp1[j] = max(dp1[j], dp1[i]+1); 50 | 51 | 52 | for(int i = n; i >= 1; --i) //notice both the loops are iterated backwards 53 | for(int j = i-1; j >= 1; --j) 54 | if(a[j] > a[i]) //condition remains the same, note it is strictly decreasing 55 | dp2[j] = max(dp2[j], dp2[i]+1); 56 | 57 | int ans = 1; 58 | rep(i, 1, n+1) 59 | ans = max(ans, dp1[i] + dp2[i] - 1); //find longest bitonic sequence 60 | cout << ans << endl; 61 | } 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /graph/kosaraju_SCC.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Finding Strongly Connected Components 3 | Kosaraju's 2 pass algorithm 4 | Time Complexity: O(V+E) 5 | Author: Chandan Mittal 6 | handle: calmhandtitan 7 | */ 8 | 9 | #include 10 | #define SZ(c) (int)((c).size()) 11 | #define VI vector 12 | #define pb push_back 13 | #define CLR(p) memset(p, 0, sizeof (p)) 14 | using namespace std; 15 | 16 | 17 | const int MAX = 100010; 18 | 19 | int n, e; 20 | bool visited[MAX]; 21 | vector g, gr; //declare 2 graphs 22 | stack s; 23 | 24 | void dfs1(int u) //simple dfs on original graph 25 | { 26 | visited[u] = 1; 27 | for(int v = 0; v < SZ(g[u]); v++) 28 | if(!visited[g[u][v]]) 29 | dfs1(g[u][v]); 30 | 31 | s.push(u); //store the nodes acc to there finish time 32 | } 33 | 34 | void dfs2(int u) //simple dfs on transpose graph 35 | { 36 | visited[u] = 1; 37 | printf("%d ", u); //print the nodes in an SCC 38 | 39 | for(int v = 0; v < SZ(gr[u]); v++) 40 | if(!visited[gr[u][v]]) 41 | dfs2(gr[u][v]); 42 | } 43 | 44 | void kosaraju_SCC() //O(n+e) algo to find SCC's in a graph 45 | { 46 | //first pass starts here 47 | CLR(visited); 48 | 49 | for(int i = 0; i < n; i++) 50 | if(!visited[i]) 51 | dfs1(i); 52 | 53 | //second pass starts here 54 | CLR(visited); 55 | 56 | while(!s.empty()) 57 | { 58 | int v = s.top(); 59 | s.pop(); 60 | 61 | if(!visited[v]) 62 | { 63 | dfs2(v); 64 | printf("\n"); 65 | } 66 | } 67 | } 68 | 69 | int main() 70 | { 71 | scanf("%d %d", &n, &e); //get the number of nodes, and edges 72 | g = vector< VI > (n); 73 | gr = vector< VI > (n); //init the transpose graph also 74 | 75 | int u, v; 76 | for(int i = 0; i < e; i++) 77 | { 78 | scanf("%d %d", &u, &v); 79 | u--, v--; //it is assumed that input nodes are 1-based indexed 80 | g[u].pb(v); 81 | gr[v].pb(u); //create the transpose graph 82 | } 83 | kosaraju_SCC(); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /graph/bellmanFord.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Single Source Shortest Path with negative edge weights 3 | Bellman Ford Algorithm 4 | Time Complexity: O(V*E) 5 | Author: Chandan Mittal 6 | handle: calmhandtitan 7 | */ 8 | 9 | #include 10 | #define pb push_back 11 | #define mp make_pair 12 | #define VI vector 13 | #define pii pair 14 | #define F first 15 | #define S second 16 | using namespace std; 17 | 18 | const int MAX = 1010; 19 | const int INF = 1<<30; 20 | 21 | vector< pair > g; //declare graph made of edges 22 | int dist[MAX]; 23 | int n, e; 24 | 25 | void printDist(int s) 26 | { 27 | printf("distance from vertex %d\n", s); 28 | for(int i = 0; i < n; i++) 29 | printf("%d\t%d\n", i, dist[i]); 30 | } 31 | 32 | void bFord(int s) 33 | { 34 | for(int i = 0; i < n; i++) 35 | dist[i] = INF; 36 | dist[s] = 0; 37 | 38 | for(int i = 1; i < n; i++) //loop n-1 times 39 | { 40 | for(int j = 0; j < e; j++) //loop over all edges 41 | { 42 | int u = g[j].S.F; 43 | int v = g[j].S.S; 44 | int w = g[j].F; 45 | 46 | if(dist[u]!=INF && dist[u] + w < dist[v]) //relax 47 | dist[v] = dist[u] + w; 48 | } 49 | } 50 | 51 | for(int j = 0; j < e; j++) 52 | { 53 | int u = g[j].S.F; 54 | int v = g[j].S.S; 55 | int w = g[j].F; 56 | 57 | if(dist[u] != INF && dist[v] > dist[u] + w) 58 | { 59 | printf("Graph has negative wt cycle\n"); 60 | } 61 | } 62 | printDist(s); 63 | } 64 | 65 | int main() 66 | { 67 | scanf("%d %d", &n, &e); 68 | 69 | //graph is not initialized as in the case of simple DFS or BFS 70 | 71 | int u, v, wt, s; 72 | for(int i = 0; i < e; i++) 73 | { 74 | scanf("%d %d %d", &u, &v, &wt); 75 | u--, v--; //assuming input nodes are 1-based indexed 76 | g.pb(mp(wt, mp(u, v))); //edges are pushed in graph 77 | } 78 | 79 | scanf("%d", &s); //get source vertex 80 | s--; 81 | bFord(s); //call bellman Ford on source vertex 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /graph/topologicalSort.cpp: -------------------------------------------------------------------------------- 1 | //Topological Sort in DAG 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define SET(p) memset(p, -1, sizeof(p)) 8 | #define CLR(p) memset(p, 0, sizeof(p)) 9 | #define CLRB(p) memset(p , false, sizeof(p)) 10 | 11 | vector< vector > graph; 12 | const int MAX = 100; 13 | int topo[200], dep_time[MAX], arr_time[MAX], tym; 14 | bool visited[MAX]; 15 | 16 | void DFS_stack(int v) 17 | { 18 | visited[v] = true; 19 | stack S; 20 | S.push(v); 21 | 22 | while(!S.empty()) 23 | { 24 | int cur = S.top(); 25 | S.pop(); 26 | 27 | printf("doing dfs for %d\n",cur); 28 | arr_time[cur] = tym++; 29 | for(vector::iterator it = graph[cur].begin(); it != graph[cur].end(); it++ ) 30 | { 31 | if(!visited[*it]) 32 | { 33 | S.push(*it); 34 | visited[*it] = true; 35 | } 36 | } 37 | topo[tym] = cur; 38 | dep_time[cur] = tym++; 39 | } 40 | } 41 | 42 | void DFS_recur(int v) 43 | { 44 | // printf("doing dfs for %d\n",v); 45 | arr_time[v] = tym++; 46 | visited[v] = true; 47 | for(vector::iterator it = graph[v].begin(); it != graph[v].end(); it++) 48 | { 49 | if(!visited[*it]) 50 | { 51 | DFS_recur(*it); 52 | } 53 | } 54 | topo[tym] = v; 55 | dep_time[v] = tym++; 56 | } 57 | 58 | int main() 59 | { 60 | int n, m, x, y; 61 | scanf("%d %d",&n,&m); 62 | graph = vector > (n); 63 | for(int i = 0; i < m; i++) 64 | { 65 | scanf("%d %d",&x,&y); 66 | graph[x].push_back(y); 67 | } 68 | // printf("here\n"); 69 | tym = 0; 70 | for(int i = 0; i <= 2*n; i++) 71 | topo[i] = -1; 72 | // DFS_stack(0); 73 | DFS_recur(0); 74 | /* 75 | printf("printing departure time\n"); 76 | for(int i = 0 ; i< n;i++) 77 | { 78 | printf("%d ",dep_time[i]); 79 | } 80 | printf("\n"); 81 | */ 82 | printf("printing topo sort\n"); 83 | for(int i = 2*n ; i > 0 ; i--) 84 | { 85 | if(topo[i] != -1) 86 | { 87 | printf("%d ",topo[i]); 88 | } 89 | } 90 | printf("\n"); 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /graph/Kruskal_MST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define pii pair 4 | #define pip pair 5 | #define F first 6 | #define S second 7 | #define MAX 10010 8 | 9 | class Union_Find 10 | { 11 | int parent[MAX], sz[MAX]; 12 | public: 13 | Union_Find(int n) 14 | { 15 | for(int i = 0; i <= n; i++) 16 | { 17 | parent[i] = i; 18 | sz[i] = 1; 19 | } 20 | } 21 | 22 | int root(int i) 23 | { 24 | while(i != parent[i]) 25 | { 26 | parent[i] = parent[parent[i]]; 27 | i = parent[i]; 28 | } 29 | return i; 30 | } 31 | 32 | int find(int p, int q) 33 | { 34 | return root(p) == root(q); 35 | } 36 | 37 | int unite(int p, int q) 38 | { 39 | int i = root(p); 40 | int j = root(q); 41 | 42 | if(sz[i] < sz[j]) 43 | { 44 | parent[i] = parent[j]; 45 | sz[j] += sz[i]; 46 | } 47 | else 48 | { 49 | parent[j] = parent[i]; 50 | sz[i] += sz[j]; 51 | } 52 | } 53 | 54 | 55 | }; 56 | 57 | vector< pip > graph; 58 | int nodes, edges; 59 | 60 | void view() 61 | { 62 | int sz = graph.size(); 63 | for(int i = 0; i< sz; i++) 64 | { 65 | printf("%d ---%d--->> %d\n",graph[i].S.F, graph[i].F, graph[i].S.S); 66 | } 67 | } 68 | 69 | long long Kruskal_MST() 70 | { 71 | Union_Find UF(nodes+1); 72 | long long T = 0; 73 | int u, v; 74 | 75 | for(int i = 0; i < edges; i++) 76 | { 77 | u = graph[i].S.F; 78 | v = graph[i].S.S; 79 | if(!UF.find(u,v )) 80 | { 81 | UF.unite(u, v); 82 | T += graph[i].F; 83 | } 84 | } 85 | return T; 86 | } 87 | 88 | int main() 89 | { 90 | int u, v, wt; 91 | scanf("%d %d",&nodes, &edges); 92 | 93 | for(int i = 0;i < edges; i++) 94 | { 95 | scanf("%d %d %d",&u, &v, &wt); 96 | graph.push_back(pip(wt, pii(u,v))); 97 | } 98 | sort(graph.begin(), graph.end()); 99 | 100 | view(); 101 | 102 | long long ans = Kruskal_MST(); 103 | printf("Length of MST is %lld\n",ans); 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /graph/LCA_logn.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define VI vector 4 | 5 | const int MAXN = 1024; 6 | int n; 7 | vector< VI > graph; 8 | bool visited[MAXN]; 9 | int parent[MAXN], Level[MAXN]; 10 | int P[MAXN][10]; //MAXN*log2(MAXN) 11 | 12 | void bfs(int v) 13 | { 14 | queue< int > Q; 15 | Q.push(v); 16 | parent[v] = v; 17 | Level[v] = 0; 18 | 19 | while(!Q.empty()) 20 | { 21 | int cur = Q.front(); 22 | Q.pop(); 23 | visited[cur] = true; 24 | 25 | for (VI::iterator it = graph[cur].begin(); it != graph[cur].end(); ++it) 26 | { 27 | if(!visited[*it]) 28 | { 29 | Q.push(*it); 30 | parent[*it] = cur; 31 | Level[*it] = Level[cur] + 1; 32 | } 33 | } 34 | } 35 | } 36 | 37 | void pre_LCA() 38 | { 39 | for (int i = 0; i < n; i++) 40 | for (int j = 0; 1 << j < n; j++) 41 | P[i][j] = -1; // Here, P[i][j] is 2j'th ancestor of i 42 | 43 | for (int i = 0; i < n; ++i) 44 | P[i][0] = parent[i]; 45 | 46 | for (int j = 1; 1 << j < n; ++j) 47 | for (int i = 0; i < n; ++i) 48 | if(P[i][j-1] != -1) 49 | P[i][j] = P[P[i][j-1]][j-1]; 50 | 51 | } 52 | 53 | int query_LCA(int p, int q) 54 | { 55 | if(Level[p] < Level[q]) 56 | swap(p, q); 57 | 58 | int LOG = log2(Level[p]); 59 | 60 | for (int i = LOG; i >= 0; --i) 61 | if(Level[p] - (1<= Level[q]) 62 | p = P[p][i]; 63 | 64 | if(p == q) 65 | return p; 66 | 67 | for (int i = LOG; i >= 0; --i) 68 | if(P[p][i] != -1 && P[p][i] != P[q][i]) 69 | p = P[p][i], q = P[q][i]; 70 | 71 | return parent[p]; 72 | } 73 | 74 | int main() 75 | { 76 | int k, x, y; 77 | scanf("%d", &n); 78 | graph = vector< VI > (n); 79 | for (int i = 0; i < n-1; ++i) 80 | { 81 | scanf("%d %d", &x, &y); 82 | x--, y--; 83 | graph[x].push_back(y); 84 | } 85 | bfs(0); 86 | pre_LCA(); 87 | 88 | 89 | scanf("%d", &k); //no of queries 90 | while(k--) 91 | { 92 | scanf("%d %d", &x, &y); 93 | x--, y--; 94 | int ans = query_LCA(x, y); 95 | printf("%d\n", ans + 1); 96 | } 97 | 98 | return 0; 99 | } -------------------------------------------------------------------------------- /DataStructures/BIT/BIT3.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "string.h" 4 | #define CLR(d) memset(d, 0, sizeof(d)) 5 | #define lli long long int 6 | 7 | int inline inp() 8 | { 9 | int n=0; 10 | char c=getchar_unlocked(); 11 | while(c < '0' || c >'9') {c=getchar_unlocked();} 12 | while(c>='0' && c<='9') 13 | { 14 | n=(n<<3)+(n<<1)+c-'0'; 15 | c=getchar_unlocked(); 16 | } 17 | return n; 18 | } 19 | 20 | int n; 21 | lli BIT1[100010], BIT2[100010]; 22 | 23 | lli query1(int k) 24 | { 25 | lli s = 0; 26 | while( k > 0) 27 | { 28 | s += BIT1[k]; 29 | k -= k & -k; 30 | } 31 | return s; 32 | } 33 | 34 | void update1(int k, lli v) 35 | { 36 | while(k <= n) 37 | { 38 | BIT1[k] += v; 39 | k += k & -k; 40 | } 41 | } 42 | 43 | lli query2(int k) 44 | { 45 | lli s = 0; 46 | while( k > 0) 47 | { 48 | s += BIT2[k]; 49 | k -= k & -k; 50 | } 51 | return s; 52 | } 53 | 54 | void update2(int k, lli v) 55 | { 56 | while(k <= n) 57 | { 58 | BIT2[k] += v; 59 | k += k & -k; 60 | } 61 | } 62 | 63 | int main() 64 | { 65 | int t, c, p, q, z; 66 | lli v1, v2, v; 67 | t = inp(); 68 | while(t--) 69 | { 70 | CLR(BIT1); 71 | CLR(BIT2); 72 | n = inp(); 73 | c = inp(); 74 | 75 | while(c--) 76 | { 77 | z = inp(); 78 | if(z) // query 79 | { 80 | p = inp(); 81 | q = inp(); 82 | v1 = query1(q)*q - query2(q); 83 | v2 = query1(p-1)*(p-1) - query2(p-1); 84 | printf("%lld\n",v1 - v2 ); 85 | } 86 | else 87 | { 88 | p = inp(); 89 | q = inp(); 90 | scanf("%lld",&v); 91 | update1(p, v); 92 | update1(q+1, -v); 93 | update2(p, v*(p-1)); 94 | update2(q+1, -v*q); 95 | } 96 | } 97 | } 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /dp/subMatrixWithAll1s.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAXROW 100 4 | #define MAXCOL 100 5 | 6 | int Histogram(int *histo, int n) 7 | { 8 | /* 9 | returns the largest area rectangle in a histogram 10 | Complexity: O(n) 11 | */ 12 | stack heights, index; 13 | int largestArea = 0; 14 | 15 | for(int i = 0; i < n; i++) 16 | { 17 | //case 1. current height is larger than that at TOS 18 | if(heights.empty() || histo[i] > heights.top()) //or of stack is empty 19 | { 20 | heights.push(histo[i]); 21 | index.push(i); 22 | } 23 | //case 2. current height is less than that at TOS 24 | else if(histo[i] < heights.top()) 25 | { 26 | int lastIndex = 0; 27 | //if the current height is shorter, we need to pop those longer heights 28 | //and compute the current rectangle area 29 | while(!heights.empty() && histo[i] < heights.top()) 30 | { 31 | //compute current area 32 | lastIndex = index.top(); 33 | int tempArea = heights.top() * (i - lastIndex); 34 | heights.pop(), index.pop(); 35 | largestArea = max(tempArea, largestArea); 36 | } 37 | heights.push(histo[i]); 38 | index.push(lastIndex); 39 | } 40 | } 41 | while(!heights.empty()) 42 | { 43 | int tempArea = heights.top() * (n - index.top() ); 44 | heights.pop(), index.pop(); 45 | largestArea = max(largestArea, tempArea); 46 | } 47 | return largestArea; 48 | } 49 | int M[MAXROW][MAXCOL]; 50 | int subMatrixWithAll1s(int ROW, int COL) 51 | { 52 | /* 53 | returns the area of largest sub matrix with all 1's 54 | Complexity: O(n^2) 55 | */ 56 | for(int i = 1; i < ROW; i++) 57 | for(int j = 0; j < COL; j++) 58 | if(M[i][j] == 1) 59 | M[i][j] = M[i-1][j] + 1; 60 | 61 | int maxArea = 0; 62 | for(int i = 0; i < ROW; i++) 63 | { 64 | int sum = Histogram(M[i], COL); 65 | maxArea = max(maxArea, sum); 66 | } 67 | return maxArea; 68 | 69 | } 70 | 71 | int main() 72 | { 73 | int ROW, COL; 74 | scanf("%d %d", &ROW, &COL); 75 | for(int i = 0; i < ROW; i++) 76 | for(int j = 0; j < COL; j++) 77 | { 78 | scanf("%d", &M[i][j]); 79 | } 80 | int ans = subMatrixWithAll1s(ROW, COL); 81 | printf("%d\n", ans); 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /graph/0-1BFS.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a weighted graph G with V vertices and E edges. 3 | Edge weights can only be 0 and x(x >= 0) 4 | Find single source shortest path from source vertex. 5 | 6 | Algo: BFS 7 | Time Complexity: O(E+V) 8 | */ 9 | #include "bits/stdc++.h" 10 | #define sd(n) scanf("%d", &(n)) 11 | #define rep(i, x, n) for (int i = x, _n = (n); i < _n; ++i) 12 | #define repi(i, a) for(typeof((a).begin()) i = (a).begin(), _##i = (a).end(); i != _##i; ++i) 13 | #define SZ(c) (int)(c).size() 14 | #define pra(v, n) rep(i, 0, n) cout << v[i] << " "; cout << endl; 15 | #define lcm(a,b) (a*(b/__gcd(a,b))) 16 | #define VI vector 17 | #define all(c) (c).begin(), (c).end() 18 | #define pb push_back 19 | #define mii map 20 | #define pii pair 21 | #define pip pair 22 | #define F first 23 | #define S second 24 | #define mp make_pair 25 | #define lli long long int 26 | #define llu unsigned long long 27 | #define CLR(p) memset(p, 0, sizeof(p)) 28 | #define SET(p) memset(p, -1, sizeof(p)) 29 | #define INF 0x3f3f3f3f 30 | #define pi 3.14159265358979 31 | #define debug 0 32 | using namespace std; 33 | 34 | const int MOD = 1e9+7; 35 | const int eps = 1e-8; 36 | const int MAX = 100010; 37 | 38 | int n, m; 39 | vector< pii> g[MAX]; 40 | int dist[MAX]; 41 | 42 | void bfs(int src) 43 | { 44 | rep(i, 0, n) 45 | dist[i] = INF; 46 | dist[src] = 0; 47 | 48 | deque d; 49 | d.push_front(src); 50 | 51 | while(!d.empty()) 52 | { 53 | int u = d.front(); 54 | d.pop_front(); 55 | 56 | rep(i, 0, SZ(g[u])) 57 | { 58 | int v = g[u][i].F; 59 | int w = g[u][i].S; 60 | if(dist[u] + w < dist[v]) 61 | { 62 | dist[v] = dist[u] + w; 63 | if(w == 1) //assuming edge-weights are 0 and 1 64 | d.push_back(v); 65 | else 66 | d.push_front(v); 67 | } 68 | } 69 | } 70 | 71 | } 72 | 73 | int main() 74 | { 75 | ios_base::sync_with_stdio(0); 76 | int a, b, w; 77 | cin >> n >> m; 78 | rep(i, 0, m) 79 | { 80 | cin >> a >> b >> w; 81 | a--, b--; //make nodes 0-based index 82 | g[a].pb(pii(b, w)); 83 | g[b].pb(pii(a, w)); 84 | } 85 | int src; 86 | cin >> src; 87 | bfs(src-1); 88 | 89 | rep(i, 0, n) 90 | cout << dist[i] << " "; 91 | cout << endl; 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /graph/checkBridge.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | check if an edge is bridge or not in unidrected graph 3 | Complexity: O(V + E) per query 4 | handle: calmhandtitan 5 | */ 6 | #include "bits/stdc++.h" 7 | #define sd(n) scanf("%d", &(n)) 8 | #define rep(i, x, n) for (int i = x, _n = (n); i < _n; ++i) 9 | #define repi(i, a) for(typeof((a).begin()) i = (a).begin(), _##i = (a).end(); i != _##i; ++i) 10 | #define pra(v) repi(it, v) cout << *it << " "; cout << endl; 11 | #define SZ(c) (int)(c).size() 12 | #define lcm(a,b) (a*(b/__gcd(a,b))) 13 | #define VI vector 14 | #define all(c) (c).begin(), (c).end() 15 | #define allr(c) (c).rbegin(), (c).rend() 16 | #define pb push_back 17 | #define mii map 18 | #define pii pair 19 | #define pip pair 20 | #define F first 21 | #define S second 22 | #define mp make_pair 23 | #define lli long long int 24 | #define llu unsigned long long 25 | #define CLR(p) memset(p, 0, sizeof(p)) 26 | #define SET(p) memset(p, -1, sizeof(p)) 27 | #define INF 0x3f3f3f3f 28 | #define pi 3.141592653589793 29 | #define debug 0 30 | using namespace std; 31 | 32 | const int MOD = 1e9+7; 33 | const int MAX = 1010; 34 | const double eps = -1e8; 35 | 36 | int n, m, x, y, q, g[MAX][MAX]; 37 | bool vis[MAX]; 38 | 39 | void dfs(int x) 40 | { 41 | vis[x] = 1; 42 | rep(i, 0, n) 43 | if(g[x][i] and !vis[i]) 44 | dfs(i); 45 | } 46 | 47 | int get(int x) 48 | { 49 | dfs(x); 50 | int cnt = 0; 51 | rep(i, 0, n) 52 | if(vis[i]) cnt++; 53 | return cnt; 54 | } 55 | 56 | int main() 57 | { 58 | ios_base::sync_with_stdio(0); 59 | sd(n); 60 | sd(m); 61 | rep(i, 0, m) 62 | { 63 | sd(x); 64 | sd(y); 65 | x--, y--; 66 | g[x][y] = g[y][x] = 1; 67 | } 68 | sd(q); 69 | while(q--) 70 | { 71 | sd(x); 72 | sd(y); 73 | x--, y--; //check if edge x-y is bridge or not 74 | 75 | CLR(vis); 76 | int cnt1 = get(x); //find number of vertices reachable from x 77 | g[x][y]--, g[y][x]--; //delete edge x--y 78 | CLR(vis); 79 | int cnt2 = get(x); //find number of vertices reachable from x 80 | g[x][y]++, g[y][x]++; //recover 81 | 82 | if(cnt1 == cnt2) //if no of vertices reachable reamins same 83 | printf("edge %d -- %d is not a bridge edge\n", x+1, y+1); 84 | else 85 | printf("edge %d -- %d is a bridge edge\n", x+1, y+1); 86 | } 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /graph/check_bipartite.cpp: -------------------------------------------------------------------------------- 1 | //SPOJ BUGLIGE solution 2 | //check if given graph is bipartite or not 3 | #include "stdio.h" 4 | #include "queue" 5 | #include "algorithm" 6 | #include "string.h" 7 | #define all(c) (c).begin(),(c).end() 8 | #define pb push_back 9 | #define VI vector 10 | using namespace std; 11 | 12 | vector graph; 13 | VI colorArr; 14 | 15 | int inline inp() 16 | { 17 | int n=0; 18 | char c=getchar_unlocked(); 19 | while(c < '0' || c >'9') {c=getchar_unlocked();} 20 | while(c>='0' && c<='9') 21 | { 22 | n=(n<<3)+(n<<1)+c-'0'; 23 | c=getchar_unlocked(); 24 | } 25 | return n; 26 | } 27 | 28 | bool check_bipartite(int src,int n) 29 | { 30 | // printf("here\n"); 31 | queue Q; 32 | Q.push(src); 33 | 34 | 35 | // int colorArr[n]; 36 | //value -1 of colorArr is used to indicate that no color is assigned yet 37 | // memset(colorArr, -1, sizeof(colorArr)); 38 | colorArr[src] = 1; //assign first color to source 39 | 40 | while(!Q.empty()) 41 | { 42 | int i = Q.front(); //dequeue a vertex from queue 43 | Q.pop(); 44 | 45 | for (VI::iterator it = graph[i].begin(); it != graph[i].end(); ++it) 46 | { 47 | if(colorArr[*it] == -1) 48 | { 49 | colorArr[*it] = 1 - colorArr[i]; 50 | Q.push(*it); 51 | } 52 | else if(colorArr[*it] == colorArr[i]) 53 | return false; 54 | } 55 | } 56 | return true; 57 | } 58 | 59 | 60 | int main() 61 | { 62 | int n,m,p,q,t,iter=0; 63 | t = inp(); 64 | while(t--) 65 | { 66 | n = inp(); 67 | m = inp(); 68 | 69 | graph = vector (n); 70 | colorArr = VI (n,-1); 71 | for (int i = 0; i < m; ++i) 72 | { 73 | p = inp(); 74 | q = inp(); 75 | p--;q--; 76 | graph[p].pb(q); 77 | graph[q].pb(p); 78 | } 79 | printf("Scenario #%d:\n",++iter); 80 | int j; 81 | for (j = 0; j < n; ++j) 82 | { 83 | if(colorArr[j] == -1) 84 | if(!check_bipartite(j,n)) 85 | { 86 | printf("Suspicious bugs found!\n"); 87 | break; 88 | } 89 | } 90 | if(j == n) 91 | printf("No suspicious bugs found!\n"); 92 | /* 93 | for (int i = 0; i < n; ++i) 94 | { 95 | printf("%d ",colorArr[i] ); 96 | } 97 | printf("\n"); 98 | */ 99 | } 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /DataStructures/sparse table/2D_RMQ.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 2D Range minimum query using Sparse table 3 | Time Complexity: 4 | Space Complexity: O(N*M*logN*logM) 5 | */ 6 | #include "bits/stdc++.h" 7 | using namespace std; 8 | 9 | const int MOD = 1e9+7; 10 | const int MAX = 1<<10; 11 | 12 | int a[MAX][MAX]; 13 | int table[MAX][10+2][MAX][10+2]; 14 | /* 15 | table[i][x][j][y] is the minimum value from column j to j+2^y-1 in all rows from i to i+2^x-1 16 | in other words, 17 | table[i][x][j][y] is the minimum value in submatrix [ (i, j) to (i+2^x-1, j+2^y-1) ] 18 | */ 19 | 20 | /* we have to query submatrix [(x1, y1), (x2, y2)]*/ 21 | int query(int x1, int y1, int x2, int y2) 22 | { 23 | int lenx = x2-x1+1; 24 | int leny = y2-y1+1; 25 | int kx = log2(lenx); 26 | int ky = log2(leny); 27 | 28 | int min_r1 = min(table[x1][kx][y1][ky], table[x1][kx][y2+1-(1< 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct node 8 | { 9 | int prefix_count; 10 | bool isEnd; 11 | struct node *child[26]; 12 | }*head; 13 | 14 | void init() 15 | { 16 | // head = (node*)malloc(sizeof(node)); 17 | head = new node(); 18 | head->isEnd = false; 19 | head->prefix_count = 0; 20 | } 21 | 22 | void insert(string word) 23 | { 24 | node *current = head; 25 | current->prefix_count++; 26 | 27 | for(int i = 0 ; i < word.length(); ++i) 28 | { 29 | int letter = (int)word[i] - (int)'a'; //extrct first character of word 30 | if(current->child[letter] == NULL) 31 | current->child[letter] = new node(); 32 | 33 | current->child[letter]->prefix_count++; 34 | current = current->child[letter]; 35 | } 36 | current->isEnd = true; 37 | } 38 | 39 | bool search(string word) 40 | { 41 | node *current = head; 42 | for(int i = 0 ; i < word.length(); ++i) 43 | { 44 | int letter = (int)word[i] - (int)'a'; 45 | if(current->child[letter] == NULL) 46 | return false; //not found 47 | current = current->child[letter]; 48 | } 49 | return current->isEnd; 50 | } 51 | 52 | int words_with_prefix(string prefix) 53 | { 54 | node *current = head; 55 | for(int i = 0; i < prefix.length() ; ++i) 56 | { 57 | int letter = (int)prefix[i] - (int)'a'; 58 | if(current->child[letter] == NULL) 59 | return 0; 60 | else 61 | current = current->child[letter]; 62 | } 63 | return current->prefix_count; 64 | } 65 | 66 | 67 | int main() 68 | { 69 | init(); 70 | string s = "chandan"; 71 | insert(s); 72 | s = "mittal"; 73 | insert(s); 74 | s = "chirag"; 75 | insert(s); 76 | s = "shashank"; 77 | insert(s); 78 | s = "abhinav"; 79 | insert(s); 80 | s = "arun"; 81 | insert(s); 82 | s = "abhishek"; 83 | insert(s); 84 | 85 | 86 | if(search("chandan")) 87 | printf("found chandan\n"); 88 | if(search("arun")) 89 | printf("found arun\n"); 90 | if(search("abhi")) 91 | printf("found abhi\n"); 92 | else 93 | printf("not found abhi\n"); 94 | 95 | printf("no of words with prefix abhi are %d\n",words_with_prefix("abhi")); 96 | printf("no of words with prefix ch are %d\n",words_with_prefix("ch")); 97 | printf("no of words with prefix k are %d\n ",words_with_prefix("k")); 98 | 99 | 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /graph/articulationPoint.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define VI vector 3 | #define all(c) c.begin(), c.end() 4 | #define lli long long int 5 | #define CLR(p) memset(p, 0, sizeof(p)) 6 | #define SET(p) memset(p, -1, sizeof(p)) 7 | using namespace std; 8 | 9 | const int MAX = 3001; 10 | int n; 11 | vector< VI> graph; 12 | int color[MAX], arr_time[MAX], LOW[MAX], pred[MAX]; 13 | int tym = 0; 14 | bool art[MAX]; 15 | 16 | int Art_point(int src) 17 | { 18 | // printf("doing dfs for %d\n",src ); 19 | color[src] = 1; //color gray 20 | 21 | LOW[src] = arr_time[src] = ++tym; 22 | 23 | for (int i = 0; i < graph[src].size(); ++i) 24 | { 25 | int w = graph[src][i]; 26 | if(!color[w]) //if color is white or it is unvisited yet 27 | { 28 | pred[w] = src; 29 | Art_point(w); 30 | 31 | if(pred[src] == -1) 32 | { 33 | //v has no predecessor, so v is the root 34 | if(i >= 1) //if 'w' is src's 2nd child or more, src is cut-vertex 35 | art[src] = true; 36 | 37 | } 38 | else if(LOW[w] >= arr_time[src]) 39 | art[src] = true; 40 | 41 | LOW[src] = min(LOW[src], LOW[w]); 42 | } 43 | else if(w != pred[src]) 44 | { 45 | //(src,w) is a back-edge 46 | LOW[src] = min(LOW[src], arr_time[w]); 47 | } 48 | 49 | } 50 | color[src] = 2; 51 | } 52 | 53 | int main() 54 | { 55 | int e, x, y; 56 | printf("Enter no of nodes(<100) and no of edges>>"); 57 | scanf("%d %d",&n,&e); 58 | graph = vector (n); 59 | for (int i = 0; i < e; ++i) 60 | { 61 | scanf("%d %d",&x,&y); 62 | graph[x].push_back(y); 63 | graph[y].push_back(x); //undirected graph 64 | } 65 | 66 | SET(pred); //initialize pred array with -1 67 | 68 | memset(art, false, sizeof(art)); 69 | 70 | Art_point(0); 71 | /* 72 | printf("\n"); 73 | printf("printing LOW array \n"); 74 | for (int i = 0; i < n; ++i) 75 | { 76 | printf("%d ",LOW[i] ); 77 | } 78 | printf("\n"); 79 | 80 | 81 | printf("printing Arrival time array \n"); 82 | for (int i = 0; i < n; ++i) 83 | { 84 | printf("%d ",arr_time[i] ); 85 | } 86 | printf("\n"); 87 | */ 88 | printf("printing Art_point array \n"); 89 | for (int i = 0; i < n; ++i) 90 | { 91 | printf("%d ",art[i]?1:0 ); 92 | } 93 | printf("\n"); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /graph/LCA_new.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Lowest common ancestor 3 | Time complexity: 4 | Algo: dfs + ancestor + dep time 5 | handle: calmhandtitan 6 | */ 7 | #include "bits/stdc++.h" 8 | #define sd(n) scanf("%d", &(n)) 9 | #define rep(i, x, n) for (int i = x, _n = (n); i < _n; ++i) 10 | #define repi(i, a) for(typeof((a).begin()) i = (a).begin(), _##i = (a).end(); i != _##i; ++i) 11 | #define pra(v) repi(it, v) cout << *it << " "; cout << endl; 12 | #define SZ(c) (int)(c).size() 13 | #define lcm(a,b) (a*(b/__gcd(a,b))) 14 | #define VI vector 15 | #define all(c) (c).begin(), (c).end() 16 | #define allr(c) (c).rbegin(), (c).rend() 17 | #define pb push_back 18 | #define mii map 19 | #define pii pair 20 | #define pip pair 21 | #define F first 22 | #define S second 23 | #define mp make_pair 24 | #define lli long long int 25 | #define llu unsigned long long 26 | #define CLR(p) memset(p, 0, sizeof(p)) 27 | #define SET(p) memset(p, -1, sizeof(p)) 28 | #define INF 0x3f3f3f3f 29 | #define pi 3.14159265358979 30 | #define debug 0 31 | using namespace std; 32 | 33 | const int MOD = 1e9+7; 34 | const int MAX = 100010; 35 | 36 | VI g[MAX]; 37 | int tin[MAX], tout[MAX], timer, dep[MAX]; 38 | int up[MAX][20]; 39 | 40 | void clear() 41 | { 42 | rep(i, 0, MAX) 43 | g[i].clear(); 44 | timer = 0; 45 | CLR(tin); 46 | CLR(tout); 47 | CLR(dep); 48 | CLR(up); 49 | } 50 | 51 | void dfs(int s, int p) 52 | { 53 | tin[s] = timer++; 54 | up[s][0] = p; 55 | rep(i, 1, 19) //up[s][i] is 2^i'th ancestor of s 56 | up[s][i] = up[up[s][i-1]][i-1]; //precompute ancestors for each node 57 | rep(i, 0, SZ(g[s])) 58 | { 59 | int v = g[s][i]; 60 | if(v == p) continue; 61 | dep[v] = dep[s] + 1; 62 | dfs(v, s); 63 | } 64 | tout[s] = timer++; 65 | } 66 | 67 | bool upper(int a, int b) //return true if a is ancestor of b 68 | { 69 | return (tin[a] <= tin[b] and tout[a] >= tout[b]); 70 | } 71 | 72 | int lca(int a, int b) //return lca of a and b 73 | { 74 | if(upper(a, b)) 75 | return a; 76 | if(upper(b, a)) 77 | return b; 78 | for(int i = 18; i >= 0; i--) 79 | if(!upper(up[a][i], b)) 80 | a = up[a][i]; 81 | return up[a][0]; 82 | } 83 | 84 | int getdist(int a, int b) //return distance between 2 nodes a and b 85 | { 86 | int q = lca(a, b); 87 | return dep[a] + dep[b] - 2*dep[q]; 88 | } 89 | 90 | int main() 91 | { 92 | ios_base::sync_with_stdio(0); 93 | int n, u, v, q; 94 | scanf("%d", &n); //get the number of nodes in tree 95 | clear(); //clear the arrays 96 | rep(i, 1, n) //read the tree edges 97 | { 98 | scanf("%d %d", &u, &v); 99 | u--,v--; 100 | g[u].pb(v); 101 | g[v].pb(u); //make undirected graph 102 | } 103 | dfs(0, 0); 104 | 105 | scanf("%d", &q); //read the number of LCA queries 106 | while(q--) 107 | { 108 | scanf("%d %d", &u, &v); //nodes are 1-based indexed here 109 | u--, v--; 110 | printf("LCA of %d and %d is %d\n", u+1, v+1, lca(u, v)+1); 111 | } 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /DataStructures/segmentTree/2dSegmentTree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 2D Segment Tree 3 | Finding maximum/minimum number in a submatrix in O(logN*logM) 4 | where N*M is the size of the original matrix 5 | 6 | Source: http://stackoverflow.com/questions/25121878/2d-segment-quad-tree-explanation-with-c 7 | */ 8 | #include 9 | 10 | using namespace std; 11 | 12 | #define Max 506 13 | #define INF (1 << 30) 14 | int P[Max][Max]; // container for 2D grid 15 | int st_size = MAX*MAX*4; //size for segment tree 16 | 17 | /* 2D Segment Tree node */ 18 | struct Point { 19 | int x, y, mx; 20 | Point() {} 21 | Point(int x, int y, int mx) : x(x), y(y), mx(mx) {} 22 | 23 | bool operator < (const Point& other) const { 24 | return mx < other.mx; 25 | } 26 | }; 27 | 28 | struct Segtree2d { 29 | Point T[st_size]; 30 | int n, m; 31 | 32 | // initialize and construct segment tree 33 | void init(int n, int m) { 34 | this -> n = n; 35 | this -> m = m; 36 | build(1, 1, 1, n, m); 37 | } 38 | 39 | // build a 2D segment tree from data [ (a1, b1), (a2, b2) ] 40 | // Time: O(n logn) 41 | Point build(int node, int a1, int b1, int a2, int b2) { 42 | // out of range 43 | if (a1 > a2 or b1 > b2) 44 | return def(); 45 | 46 | // if it is only a single index, assign value to node 47 | if (a1 == a2 and b1 == b2) 48 | return T[node] = Point(a1, b1, P[a1][b1]); 49 | 50 | // split the tree into four segments 51 | T[node] = def(); 52 | T[node] = maxNode(T[node], build(4 * node - 2, a1, b1, (a1 + a2) / 2, (b1 + b2) / 2 ) ); 53 | T[node] = maxNode(T[node], build(4 * node - 1, (a1 + a2) / 2 + 1, b1, a2, (b1 + b2) / 2 )); 54 | T[node] = maxNode(T[node], build(4 * node + 0, a1, (b1 + b2) / 2 + 1, (a1 + a2) / 2, b2) ); 55 | T[node] = maxNode(T[node], build(4 * node + 1, (a1 + a2) / 2 + 1, (b1 + b2) / 2 + 1, a2, b2) ); 56 | return T[node]; 57 | } 58 | 59 | // helper function for query(int, int, int, int); 60 | Point query(int node, int a1, int b1, int a2, int b2, int x1, int y1, int x2, int y2) { 61 | // if we out of range, return dummy 62 | if (x1 > a2 or y1 > b2 or x2 < a1 or y2 < b1 or a1 > a2 or b1 > b2) 63 | return def(); 64 | 65 | // if it is within range, return the node 66 | if (x1 <= a1 and y1 <= b1 and a2 <= x2 and b2 <= y2) 67 | return T[node]; 68 | 69 | // split into four segments 70 | Point mx = def(); 71 | mx = maxNode(mx, query(4 * node - 2, a1, b1, (a1 + a2) / 2, (b1 + b2) / 2, x1, y1, x2, y2) ); 72 | mx = maxNode(mx, query(4 * node - 1, (a1 + a2) / 2 + 1, b1, a2, (b1 + b2) / 2, x1, y1, x2, y2) ); 73 | mx = maxNode(mx, query(4 * node + 0, a1, (b1 + b2) / 2 + 1, (a1 + a2) / 2, b2, x1, y1, x2, y2) ); 74 | mx = maxNode(mx, query(4 * node + 1, (a1 + a2) / 2 + 1, (b1 + b2) / 2 + 1, a2, b2, x1, y1, x2, y2)); 75 | 76 | // return the maximum value 77 | return mx; 78 | } 79 | 80 | // query from range [ (x1, y1), (x2, y2) ] 81 | // Time: O(logn) 82 | Point query(int x1, int y1, int x2, int y2) { 83 | return query(1, 1, 1, n, m, x1, y1, x2, y2); 84 | } 85 | 86 | // helper function for update(int, int, int); 87 | Point update(int node, int a1, int b1, int a2, int b2, int x, int y, int value) { 88 | if (a1 > a2 or b1 > b2) 89 | return def(); 90 | 91 | if (x > a2 or y > b2 or x < a1 or y < b1) 92 | return T[node]; 93 | 94 | if (x == a1 and y == b1 and x == a2 and y == b2) 95 | return T[node] = Point(x, y, value); 96 | 97 | Point mx = def(); 98 | mx = maxNode(mx, update(4 * node - 2, a1, b1, (a1 + a2) / 2, (b1 + b2) / 2, x, y, value) ); 99 | mx = maxNode(mx, update(4 * node - 1, (a1 + a2) / 2 + 1, b1, a2, (b1 + b2) / 2, x, y, value)); 100 | mx = maxNode(mx, update(4 * node + 0, a1, (b1 + b2) / 2 + 1, (a1 + a2) / 2, b2, x, y, value)); 101 | mx = maxNode(mx, update(4 * node + 1, (a1 + a2) / 2 + 1, (b1 + b2) / 2 + 1, a2, b2, x, y, value) ); 102 | return T[node] = mx; 103 | } 104 | 105 | // update the value of (x, y) index to 'value' 106 | // Time: O(logn) 107 | Point update(int x, int y, int value) { 108 | return update(1, 1, 1, n, m, x, y, value); 109 | } 110 | 111 | // utility functions; these functions are virtual because they will be overridden in child class 112 | virtual Point maxNode(Point a, Point b) { 113 | return max(a, b); 114 | } 115 | 116 | // dummy node 117 | virtual Point def() { 118 | return Point(0, 0, -INF); 119 | } 120 | }; 121 | 122 | struct Segtree2dMin : Segtree2d { 123 | // overload maxNode() function to return minimum value 124 | Point maxNode(Point a, Point b) { 125 | return min(a, b); 126 | } 127 | 128 | Point def() { 129 | return Point(0, 0, INF); 130 | } 131 | }; 132 | 133 | Segtree2d Tmax; 134 | Segtree2dMin Tmin; 135 | 136 | 137 | int main(void) { 138 | int n, m; 139 | 140 | scanf("%d %d", &n, &m); 141 | for(int i = 1; i <= n; i++) 142 | for(int j = 1; j <= m; j++) 143 | scanf("%d", &P[i][j]); 144 | 145 | Tmax.init(n, m); 146 | Tmin.init(n, m); 147 | 148 | int x1, y1, x2, y2; 149 | scanf("%d %d %d %d", &x1, &y1, &x2, &y2); 150 | 151 | Tmax.query(x1, y1, x2, y2).mx; 152 | Tmin.query(x1, y1, x2, y2).mx; 153 | 154 | int x, y, v; 155 | scanf("%d %d %d", &x, &y, &v); 156 | Tmax.update(x, y, v); 157 | Tmin.update(x, y, v); 158 | 159 | return 0; 160 | } 161 | -------------------------------------------------------------------------------- /bigint.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | const int base = 1000000000; 7 | const int base_digits = 9; 8 | 9 | struct bigint { 10 | vector a; 11 | int sign; 12 | 13 | bigint() : 14 | sign(1) { 15 | } 16 | 17 | bigint(long long v) { 18 | *this = v; 19 | } 20 | 21 | bigint(const string &s) { 22 | read(s); 23 | } 24 | 25 | void operator=(const bigint &v) { 26 | sign = v.sign; 27 | a = v.a; 28 | } 29 | 30 | void operator=(long long v) { 31 | sign = 1; 32 | if (v < 0) 33 | sign = -1, v = -v; 34 | for (; v > 0; v = v / base) 35 | a.push_back(v % base); 36 | } 37 | 38 | bigint operator+(const bigint &v) const { 39 | if (sign == v.sign) { 40 | bigint res = v; 41 | 42 | for (int i = 0, carry = 0; i < (int) max(a.size(), v.a.size()) || carry; ++i) { 43 | if (i == (int) res.a.size()) 44 | res.a.push_back(0); 45 | res.a[i] += carry + (i < (int) a.size() ? a[i] : 0); 46 | carry = res.a[i] >= base; 47 | if (carry) 48 | res.a[i] -= base; 49 | } 50 | return res; 51 | } 52 | return *this - (-v); 53 | } 54 | 55 | bigint operator-(const bigint &v) const { 56 | if (sign == v.sign) { 57 | if (abs() >= v.abs()) { 58 | bigint res = *this; 59 | for (int i = 0, carry = 0; i < (int) v.a.size() || carry; ++i) { 60 | res.a[i] -= carry + (i < (int) v.a.size() ? v.a[i] : 0); 61 | carry = res.a[i] < 0; 62 | if (carry) 63 | res.a[i] += base; 64 | } 65 | res.trim(); 66 | return res; 67 | } 68 | return -(v - *this); 69 | } 70 | return *this + (-v); 71 | } 72 | 73 | void operator*=(int v) { 74 | if (v < 0) 75 | sign = -sign, v = -v; 76 | for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) { 77 | if (i == (int) a.size()) 78 | a.push_back(0); 79 | long long cur = a[i] * (long long) v + carry; 80 | carry = (int) (cur / base); 81 | a[i] = (int) (cur % base); 82 | //asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base)); 83 | } 84 | trim(); 85 | } 86 | 87 | bigint operator*(int v) const { 88 | bigint res = *this; 89 | res *= v; 90 | return res; 91 | } 92 | 93 | friend pair divmod(const bigint &a1, const bigint &b1) { 94 | int norm = base / (b1.a.back() + 1); 95 | bigint a = a1.abs() * norm; 96 | bigint b = b1.abs() * norm; 97 | bigint q, r; 98 | q.a.resize(a.a.size()); 99 | 100 | for (int i = a.a.size() - 1; i >= 0; i--) { 101 | r *= base; 102 | r += a.a[i]; 103 | int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()]; 104 | int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1]; 105 | int d = ((long long) base * s1 + s2) / b.a.back(); 106 | r -= b * d; 107 | while (r < 0) 108 | r += b, --d; 109 | q.a[i] = d; 110 | } 111 | 112 | q.sign = a1.sign * b1.sign; 113 | r.sign = a1.sign; 114 | q.trim(); 115 | r.trim(); 116 | return make_pair(q, r / norm); 117 | } 118 | 119 | bigint operator/(const bigint &v) const { 120 | return divmod(*this, v).first; 121 | } 122 | 123 | bigint operator%(const bigint &v) const { 124 | return divmod(*this, v).second; 125 | } 126 | 127 | void operator/=(int v) { 128 | if (v < 0) 129 | sign = -sign, v = -v; 130 | for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) { 131 | long long cur = a[i] + rem * (long long) base; 132 | a[i] = (int) (cur / v); 133 | rem = (int) (cur % v); 134 | } 135 | trim(); 136 | } 137 | 138 | bigint operator/(int v) const { 139 | bigint res = *this; 140 | res /= v; 141 | return res; 142 | } 143 | 144 | int operator%(int v) const { 145 | if (v < 0) 146 | v = -v; 147 | int m = 0; 148 | for (int i = a.size() - 1; i >= 0; --i) 149 | m = (a[i] + m * (long long) base) % v; 150 | return m * sign; 151 | } 152 | 153 | void operator+=(const bigint &v) { 154 | *this = *this + v; 155 | } 156 | void operator-=(const bigint &v) { 157 | *this = *this - v; 158 | } 159 | void operator*=(const bigint &v) { 160 | *this = *this * v; 161 | } 162 | void operator/=(const bigint &v) { 163 | *this = *this / v; 164 | } 165 | 166 | bool operator<(const bigint &v) const { 167 | if (sign != v.sign) 168 | return sign < v.sign; 169 | if (a.size() != v.a.size()) 170 | return a.size() * sign < v.a.size() * v.sign; 171 | for (int i = a.size() - 1; i >= 0; i--) 172 | if (a[i] != v.a[i]) 173 | return a[i] * sign < v.a[i] * sign; 174 | return false; 175 | } 176 | 177 | bool operator>(const bigint &v) const { 178 | return v < *this; 179 | } 180 | bool operator<=(const bigint &v) const { 181 | return !(v < *this); 182 | } 183 | bool operator>=(const bigint &v) const { 184 | return !(*this < v); 185 | } 186 | bool operator==(const bigint &v) const { 187 | return !(*this < v) && !(v < *this); 188 | } 189 | bool operator!=(const bigint &v) const { 190 | return *this < v || v < *this; 191 | } 192 | 193 | void trim() { 194 | while (!a.empty() && !a.back()) 195 | a.pop_back(); 196 | if (a.empty()) 197 | sign = 1; 198 | } 199 | 200 | bool isZero() const { 201 | return a.empty() || (a.size() == 1 && !a[0]); 202 | } 203 | 204 | bigint operator-() const { 205 | bigint res = *this; 206 | res.sign = -sign; 207 | return res; 208 | } 209 | 210 | bigint abs() const { 211 | bigint res = *this; 212 | res.sign *= res.sign; 213 | return res; 214 | } 215 | 216 | long long longValue() const { 217 | long long res = 0; 218 | for (int i = a.size() - 1; i >= 0; i--) 219 | res = res * base + a[i]; 220 | return res * sign; 221 | } 222 | 223 | friend bigint gcd(const bigint &a, const bigint &b) { 224 | return b.isZero() ? a : gcd(b, a % b); 225 | } 226 | friend bigint lcm(const bigint &a, const bigint &b) { 227 | return a / gcd(a, b) * b; 228 | } 229 | 230 | void read(const string &s) { 231 | sign = 1; 232 | a.clear(); 233 | int pos = 0; 234 | while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) { 235 | if (s[pos] == '-') 236 | sign = -sign; 237 | ++pos; 238 | } 239 | for (int i = s.size() - 1; i >= pos; i -= base_digits) { 240 | int x = 0; 241 | for (int j = max(pos, i - base_digits + 1); j <= i; j++) 242 | x = x * 10 + s[j] - '0'; 243 | a.push_back(x); 244 | } 245 | trim(); 246 | } 247 | 248 | friend istream& operator>>(istream &stream, bigint &v) { 249 | string s; 250 | stream >> s; 251 | v.read(s); 252 | return stream; 253 | } 254 | 255 | friend ostream& operator<<(ostream &stream, const bigint &v) { 256 | if (v.sign == -1) 257 | stream << '-'; 258 | stream << (v.a.empty() ? 0 : v.a.back()); 259 | for (int i = (int) v.a.size() - 2; i >= 0; --i) 260 | stream << setw(base_digits) << setfill('0') << v.a[i]; 261 | return stream; 262 | } 263 | 264 | static vector convert_base(const vector &a, int old_digits, int new_digits) { 265 | vector p(max(old_digits, new_digits) + 1); 266 | p[0] = 1; 267 | for (int i = 1; i < (int) p.size(); i++) 268 | p[i] = p[i - 1] * 10; 269 | vector res; 270 | long long cur = 0; 271 | int cur_digits = 0; 272 | for (int i = 0; i < (int) a.size(); i++) { 273 | cur += a[i] * p[cur_digits]; 274 | cur_digits += old_digits; 275 | while (cur_digits >= new_digits) { 276 | res.push_back(int(cur % p[new_digits])); 277 | cur /= p[new_digits]; 278 | cur_digits -= new_digits; 279 | } 280 | } 281 | res.push_back((int) cur); 282 | while (!res.empty() && !res.back()) 283 | res.pop_back(); 284 | return res; 285 | } 286 | 287 | typedef vector vll; 288 | 289 | static vll karatsubaMultiply(const vll &a, const vll &b) { 290 | int n = a.size(); 291 | vll res(n + n); 292 | if (n <= 32) { 293 | for (int i = 0; i < n; i++) 294 | for (int j = 0; j < n; j++) 295 | res[i + j] += a[i] * b[j]; 296 | return res; 297 | } 298 | 299 | int k = n >> 1; 300 | vll a1(a.begin(), a.begin() + k); 301 | vll a2(a.begin() + k, a.end()); 302 | vll b1(b.begin(), b.begin() + k); 303 | vll b2(b.begin() + k, b.end()); 304 | 305 | vll a1b1 = karatsubaMultiply(a1, b1); 306 | vll a2b2 = karatsubaMultiply(a2, b2); 307 | 308 | for (int i = 0; i < k; i++) 309 | a2[i] += a1[i]; 310 | for (int i = 0; i < k; i++) 311 | b2[i] += b1[i]; 312 | 313 | vll r = karatsubaMultiply(a2, b2); 314 | for (int i = 0; i < (int) a1b1.size(); i++) 315 | r[i] -= a1b1[i]; 316 | for (int i = 0; i < (int) a2b2.size(); i++) 317 | r[i] -= a2b2[i]; 318 | 319 | for (int i = 0; i < (int) r.size(); i++) 320 | res[i + k] += r[i]; 321 | for (int i = 0; i < (int) a1b1.size(); i++) 322 | res[i] += a1b1[i]; 323 | for (int i = 0; i < (int) a2b2.size(); i++) 324 | res[i + n] += a2b2[i]; 325 | return res; 326 | } 327 | 328 | bigint operator*(const bigint &v) const { 329 | vector a6 = convert_base(this->a, base_digits, 6); 330 | vector b6 = convert_base(v.a, base_digits, 6); 331 | vll a(a6.begin(), a6.end()); 332 | vll b(b6.begin(), b6.end()); 333 | while (a.size() < b.size()) 334 | a.push_back(0); 335 | while (b.size() < a.size()) 336 | b.push_back(0); 337 | while (a.size() & (a.size() - 1)) 338 | a.push_back(0), b.push_back(0); 339 | vll c = karatsubaMultiply(a, b); 340 | bigint res; 341 | res.sign = sign * v.sign; 342 | for (int i = 0, carry = 0; i < (int) c.size(); i++) { 343 | long long cur = c[i] + carry; 344 | res.a.push_back((int) (cur % 1000000)); 345 | carry = (int) (cur / 1000000); 346 | } 347 | res.a = convert_base(res.a, 6, base_digits); 348 | res.trim(); 349 | return res; 350 | } 351 | }; 352 | 353 | int main() 354 | { 355 | bigint a = bigint("1"); 356 | int b = 2; 357 | for(int i=1; i<100; i++) 358 | { 359 | a = a*b; 360 | } 361 | 362 | cout << a << endl; 363 | 364 | for(int i=1; i<99; i++) 365 | { 366 | a /= b; 367 | } 368 | 369 | cout << a << endl; 370 | } 371 | --------------------------------------------------------------------------------