├── .gitignore ├── Backtracking ├── 750 - 8 Queens Chess Problem.cpp ├── AllPermutations.cpp ├── Backtracking - Suduku1.cpp ├── Backtracking - Suduku2.cpp ├── KnightTour.cpp ├── NQueens.cpp ├── RIM.cpp └── SubsetSum.cpp ├── BinarySearch.cpp ├── Built-in functions 01.cpp ├── Built-in functions 02.cpp ├── CSES └── Dynamic Programming │ ├── cses1158.cpp │ ├── cses1633.cpp │ ├── cses1634.cpp │ ├── cses1635.cpp │ ├── cses1636.cpp │ ├── cses1637.cpp │ └── cses1638.cpp ├── Complexity analysis.txt ├── Cumulative Sum & Frequency Array.txt ├── DSU.cpp ├── Dynamic Programming ├── CoinChange.cpp ├── Knapsack.cpp ├── LIS.cpp ├── Longest Common Subsequence.cpp ├── MCM.cpp ├── MaximumPathSum.cpp ├── Minimum Edit Distance.cpp └── TSP.cpp ├── Graphs ├── AdjacencyList[Linked List].cpp ├── AdjacencyList[Vector].cpp ├── Dijkstra.cpp ├── FloodFill.cpp ├── Floyd.cpp ├── Graph Representation.cpp ├── Is DAG.cpp ├── Minimum Spanning Tree [Kruskal].cpp ├── Number Of Connected Components.cpp ├── SSSP.cpp ├── Topological ordering.cpp └── isBipartite.cpp ├── Kadane Algorithm ├── 1D-Kadane.cpp ├── 2D-Kadane.cpp └── 3D-Kadane.cpp ├── LICENSE ├── LIS.cpp ├── Matrices.cpp ├── Number Theory ├── Number Theory 01.cpp ├── Number Theory 03.cpp ├── Number Theory 04.cpp ├── PhiSieve.cpp ├── Sieve_Number_of_Divisors.cpp └── Sieve_Prime_Factors.cpp ├── README.md ├── STL(1 of 2).txt ├── STL2.txt ├── Segment Tree └── RSQ.cpp ├── Strings ├── KMP.cpp └── Rabin-Karp.cpp └── bitwise operations and bitmasks.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /Backtracking/750 - 8 Queens Chess Problem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e2+5 , M = 1e1, OO = 1000000007; 5 | const double EPS = 0.00001; 6 | 7 | int t, a, b, Row[10], diff[20], sum[20], sols, ans[10]; 8 | 9 | void printSolution(){ 10 | if(++sols < 10) printf(" "); 11 | printf("%d ", sols); 12 | for(int c = 1 ; c < 9 ; ++c) 13 | printf(" %d", ans[c]); 14 | puts(""); 15 | } 16 | 17 | void solve(int c = 1){ 18 | if(c == b){ 19 | solve(c+1); 20 | return; 21 | } 22 | if(c == 9){ 23 | printSolution(); 24 | return; 25 | } 26 | for(int r = 1 ; r < 9 ; ++r){ 27 | if(Row[r] || diff[8+r-c] || sum[r+c]) continue; 28 | Row[r] = diff[8+r-c] = sum[r+c] = 1; //do 29 | ans[c] = r; 30 | solve(c+1); //recurse 31 | Row[r] = diff[8+r-c] = sum[r+c] = 0; //undo 32 | } 33 | } 34 | 35 | void init(){ 36 | memset(Row, 0, sizeof Row); 37 | memset(sum, 0, sizeof sum); 38 | memset(diff, 0, sizeof diff); 39 | memset(ans, 0, sizeof ans); 40 | sols = 0; 41 | Row[a] = sum[a+b] = diff[8+a-b] = 1; 42 | ans[b] = a; 43 | } 44 | 45 | int main(){ 46 | // freopen("i.in", "rt", stdin); 47 | // freopen("o.out", "wt", stdout); 48 | scanf("%d", &t); 49 | while(t--){ 50 | puts("SOLN COLUMN\n # 1 2 3 4 5 6 7 8\n"); 51 | scanf("%d %d", &a, &b); 52 | init(); 53 | 54 | solve(); 55 | if(t) puts(""); 56 | } 57 | return 0; 58 | } 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /Backtracking/AllPermutations.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | const int N = 12 , M = 1e4 +5, OO = 0x3f3f3f3f; 6 | 7 | int n, A[N], sitted[N]; 8 | vector permutation; 9 | 10 | void printPath(){ 11 | for(int i = 0 ; i < n ; ++i) 12 | printf("%d%c", permutation[i], " \n"[i==n-1]); 13 | } 14 | 15 | void solveAP(int idx = 0){ 16 | if(idx == n){ 17 | printPath(); 18 | }else{ 19 | for(int i = 0 ; i < n ; ++i){ 20 | if(!sitted[i]){ 21 | sitted[i] = 1; //do 22 | permutation.push_back(A[i]); //do 23 | solveAP(idx+1); //recurse 24 | sitted[i] = 0; //undo 25 | permutation.pop_back(); //undo 26 | } 27 | } 28 | } 29 | } 30 | 31 | int main(){ 32 | scanf("%d", &n); 33 | for(int i = 0 ; i < n ; ++i) 34 | scanf("%d", A+i); 35 | solveAP(); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Backtracking/Backtracking - Suduku1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e5+9, M = 1e3+9, OO = 1000000007; 5 | const double EPS = 0.0000001; 6 | 7 | char grid[10][10]; 8 | int ops ; 9 | int rVis[10][10], cVis[10][10], bVis[10][10]; 10 | 11 | bool isVis(int r, int c, int val){ 12 | int b = (r/3) * 3 + c / 3; 13 | return (rVis[r][val] || cVis[c][val] || bVis[b][val]); 14 | } 15 | 16 | bool isValid(int r, int c){ 17 | int vis[12] = {}; 18 | for(int i = 0 ; i < 9 ; ++i){ //check my row 19 | if(grid[r][i] != 'x' && vis[grid[r][i] - '0']) return 0; 20 | else if(grid[r][i] != 'x') vis[grid[r][i] - '0'] = 1; 21 | } 22 | memset(vis, 0, sizeof vis); 23 | for(int i = 0 ; i < 9 ; ++i){ //check my Column 24 | if(grid[i][c] != 'x' && vis[grid[i][c] - '0']) return 0; 25 | else if(grid[i][c] != 'x') vis[grid[i][c] - '0'] = 1; 26 | } 27 | memset(vis, 0, sizeof vis); 28 | int rBox = r/3, cBox = c/3; 29 | for(int i = 0 ; i < 3 ; ++i) //check my box 30 | for(int j = 0 ; j < 3 ; ++j){ 31 | int x = 3*rBox + i, y = 3*cBox + j; 32 | if(grid[x][y] != 'x' && vis[grid[x][y] - '0']) return 0; 33 | else if(grid[x][y] != 'x') vis[grid[x][y] - '0'] = 1; 34 | } 35 | return 1; 36 | } 37 | 38 | pair nextCell(pair &x){ 39 | if(x.second == 8) return {x.first+1, 0}; 40 | return {x.first, x.second+1}; 41 | } 42 | 43 | bool isAllValid(){ 44 | for(int i = 0 ; i < 9 ; ++i) 45 | if(!isValid(i, i)) return 0; 46 | return 1; 47 | } 48 | 49 | void visit(int r, int c, int val){ 50 | int b = (r/3) * 3 + c / 3; 51 | rVis[r][val] = cVis[c][val] = bVis[b][val] = 1; 52 | } 53 | 54 | void unvisit(int r, int c, int val){ 55 | int b = (r/3) * 3 + c / 3; 56 | rVis[r][val] = cVis[c][val] = bVis[b][val] = 0; 57 | } 58 | 59 | bool solve2(pair cell){ 60 | ++ops; 61 | int r = cell.first, c = cell.second; 62 | if(r == 9) return isAllValid(); 63 | if(grid[r][c] != 'x' && isValid(r, c)) return solve2(nextCell(cell)); 64 | else if(grid[r][c] != 'x') return 0; 65 | for(char i = '1' ; i <= '9' ; ++i){ 66 | if(!isVis(r, c, i - '0')){ 67 | grid[r][c] = i; //Do 68 | visit(r, c, i - '0'); 69 | if(solve2(nextCell(cell))) return 1; //Recurse 70 | grid[r][c] = 'x'; //UnDo 71 | unvisit(r, c, i - '0'); 72 | } 73 | } 74 | return 0; 75 | } 76 | 77 | bool solve1(pair cell){ 78 | ++ops; 79 | int r = cell.first, c = cell.second; 80 | if(r == 9) return isAllValid(); 81 | if(grid[r][c] != 'x' && isValid(r, c)) return solve1(nextCell(cell)); 82 | else if(grid[r][c] != 'x') return 0; 83 | for(char i = '1' ; i <= '9' ; ++i){ 84 | grid[r][c] = i; //Do 85 | if(isValid(r, c) && solve1(nextCell(cell))) return 1; //Recurse 86 | grid[r][c] = 'x'; //UnDo 87 | } 88 | return 0; 89 | } 90 | 91 | void printGrid(){ 92 | printf("-------------------\n"); 93 | for(int i = 0 ; i < 9 ; ++i){ 94 | for(int j = 0 ; j < 9 ; ++j){ 95 | if(!j) printf("|"); 96 | printf("%c%c", grid[i][j], ((j+1)%3==0? '|' : ' ')); 97 | } 98 | puts(""); 99 | if((i+1)%3==0) printf("-------------------\n"); 100 | } 101 | } 102 | 103 | int main(){ 104 | freopen("i.in", "rt", stdin); 105 | // freopen("o.out", "wt", stdout); 106 | for(int i = 0 ; i < 9 ; ++i) 107 | scanf("%s", grid[i]); 108 | for(int i = 0 ; i < 9 ; ++i){ 109 | for(int j = 0 ; j < 9 ; ++j){ 110 | if(grid[i][j] != 'x') visit(i, j, grid[i][j] - '0'); 111 | } 112 | } 113 | if(solve2({0, 0})) printGrid(); 114 | else puts("INVALID"); 115 | printf("%d\n", ops); 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /Backtracking/Backtracking - Suduku2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e5+9, M = 1e3+9, OO = 1000000007; 5 | const double EPS = 0.0000001; 6 | 7 | char grid[10][10]; 8 | int ops ; 9 | int rVis[10][10], cVis[10][10], bVis[10][10]; 10 | 11 | pair nextCell(pair cell){ 12 | if(cell.second == 8) return {cell.first+1, 0}; 13 | return {cell.first, cell.second+1}; 14 | } 15 | 16 | bool valid(int r, int c){ 17 | for(int i = 0 ; i < 9 ; ++i){ 18 | if(i!=c && grid[r][c] == grid[r][i]) return 0; 19 | if(i!=r && grid[r][c] == grid[i][c]) return 0; 20 | } 21 | int rBox = (r/3)*3, cBox = (c/3)*3; 22 | for(int i = rBox ; i < rBox + 3 ; ++i){ 23 | for(int j = cBox ; j < cBox + 3 ; ++j){ 24 | if((i!=r || j!=c) && grid[r][c] == grid[i][j]) return 0; 25 | } 26 | } 27 | return 1; 28 | } 29 | 30 | bool solve(pair cell){ 31 | ++ops; 32 | int r = cell.first, c = cell.second; 33 | if(r == 8 && c == 8 && grid[r][c] != 'x') return 1; 34 | if(grid[r][c] != 'x') return solve(nextCell(cell)); 35 | for(char i = '1' ; i<='9' ; ++i){ 36 | grid[r][c] = i; //Do 37 | if(r == 8 && c == 8 && valid(r, c)) return 1; 38 | else if(valid(r, c) && solve(nextCell(cell))) return 1; //recurse 39 | grid[r][c] = 'x'; //undo 40 | } 41 | return 0; 42 | } 43 | 44 | void printGrid(){ 45 | printf("-------------------\n"); 46 | for(int i = 0 ; i < 9 ; ++i){ 47 | for(int j = 0 ; j < 9 ; ++j){ 48 | if(!j) printf("|"); 49 | printf("%c%c", grid[i][j], ((j+1)%3==0? '|' : ' ')); 50 | } 51 | puts(""); 52 | if((i+1)%3==0) printf("-------------------\n"); 53 | } 54 | } 55 | 56 | int main(){ 57 | freopen("i.in", "rt", stdin); 58 | // freopen("o.out", "wt", stdout); 59 | for(int i = 0 ; i < 9 ; ++i) 60 | scanf("%s", grid[i]); 61 | if(solve({0, 0})) printGrid(); 62 | else puts("INVALID"); 63 | printf("%d\n", ops); 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /Backtracking/KnightTour.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | const int N = 11, M = 1e4 +5, OO = 0x3f3f3f3f; 6 | 7 | int n, m; 8 | int visitTime[N][N]; 9 | 10 | void printPath(){ 11 | puts("---------------------------------"); 12 | for(int i = 0 ; i < n ; ++i) 13 | for(int j = 0 ; j < m ; ++j) 14 | printf("%3d%c", visitTime[i][j], " \n"[j==m-1]); 15 | puts("---------------------------------"); 16 | } 17 | 18 | bool valid(int r, int c){ //checks if the cell inside the grid and not visited 19 | return r < n && r >= 0 && c < m && c >= 0 && visitTime[r][c] == -1; 20 | } 21 | 22 | int dr[] = {1, 1, -1, -1, 2, 2, -2, -2}; 23 | int dc[] = {2, -2, 2, -2, 1, -1, 1, -1}; 24 | 25 | void solveKT(int r = 0, int c = 0, int visitedNum = 1){ 26 | if(visitedNum == n*m){ 27 | printPath(); 28 | }else{ 29 | for(int k = 0 ; k < 8 ; ++k){ //all the 8 options -directions- 30 | int nr = r + dr[k], nc = c + dc[k]; //new row, column 31 | if(valid(nr, nc)){ 32 | visitTime[nr][nc] = visitedNum; //do 33 | solveKT(nr, nc, visitedNum+1); //recurse 34 | visitTime[nr][nc] = -1; //undo 35 | } 36 | } 37 | } 38 | } 39 | 40 | int main(){ 41 | scanf("%d %d", &n, &m); 42 | memset(visitTime, -1, sizeof visitTime); 43 | visitTime[0][0] = 0; 44 | solveKT(); 45 | return 0; 46 | } 47 | 48 | //sample Input => 3 4 49 | -------------------------------------------------------------------------------- /Backtracking/NQueens.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 15 , M = 1e4 +5, OO = 0x3f3f3f3f; 5 | 6 | int n; 7 | bool col[N], md[2*N], sd[2*N]; 8 | char board[N][N]; 9 | 10 | void printGrid(){ 11 | puts("---------------------------------"); 12 | for(int i = 0 ; i < n ; ++i){ 13 | for(int j = 0; j < n ; ++j) 14 | printf("%c", board[i][j]); 15 | puts(""); 16 | } 17 | puts("---------------------------------"); 18 | } 19 | 20 | bool valid(int r, int c){ 21 | return (!col[c] && !md[r-c+N] && !sd[r+c]); 22 | } 23 | 24 | void solveNQ(int r = 0){ 25 | if(r == n){ 26 | printGrid(); 27 | }else{ 28 | for(int c = 0 ; c < n ; ++c){ 29 | if(valid(r, c)){ 30 | col[c] = md[r-c+N] = sd[r+c] = 1; //do 31 | board[r][c] = 'Q'; //do 32 | solveNQ(r+1); //recurse 33 | col[c] = md[r-c+N] = sd[r+c] = 0; //undo 34 | board[r][c] = '.'; //undo 35 | } 36 | } 37 | } 38 | } 39 | 40 | int main(){ 41 | scanf("%d", &n); 42 | for(int i = 0 ; i < n ; ++i) 43 | for(int j = 0 ; j < n ; ++j) board[i][j] = '.'; 44 | solveNQ(); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Backtracking/RIM.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int N = 10 , M = 1e4 +5, OO = 0x3f3f3f3f; 7 | 8 | int n, m; 9 | char grid[N][N]; 10 | 11 | bool valid(int r, int c){ //inside the grid and not equal # 12 | return (r=0 && c=0 && grid[r][c]!='#'); 13 | } 14 | 15 | string path; 16 | 17 | void printPath(){ 18 | printf("%s\n", path.c_str()); 19 | } 20 | 21 | bool solveRIM(int r = 0, int c = 0){ 22 | if(r == n-1 && c == m-1){ 23 | printPath(); 24 | }else{ 25 | if(valid(r+1, c)){ //Down 26 | path.push_back('D'); //do 27 | solveRIM(r+1, c); //recurse 28 | path.pop_back(); //undo 29 | } 30 | if(valid(r, c+1)){ //Right 31 | path.push_back('R'); //do 32 | solveRIM(r, c+1); //recurse 33 | path.pop_back(); //undo 34 | } 35 | } 36 | } 37 | 38 | int main(){ 39 | scanf("%d %d", &n, &m); 40 | for(int i = 0 ; i < n ; ++i) 41 | scanf("%s", grid[i]); 42 | solveRIM(); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /Backtracking/SubsetSum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | const int N = 25 , M = 1e4 +5, OO = 0x3f3f3f3f; 6 | 7 | int n, A[N], x; 8 | vector path; 9 | 10 | void printPath(){ 11 | for(int i = 0 ; i < int(path.size()) ; ++i) 12 | printf("%d%c", path[i], " \n"[i==int(path.size())-1]); 13 | } 14 | 15 | void solveSS(int i = 0, int sum = 0){ 16 | if(i == n || sum == x){ 17 | if(sum == x) printPath(); 18 | }else{ 19 | solveSS(i+1, sum); //Leave it 20 | 21 | path.push_back(A[i]); //do 22 | solveSS(i+1, sum+A[i]); //recurse -take it- 23 | path.pop_back(); //undo 24 | } 25 | } 26 | 27 | int main(){ 28 | scanf("%d %d", &n, &x); 29 | for(int i = 0 ; i < n ; ++i) scanf("%d", A+i); 30 | solveSS(); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /BinarySearch.cpp: -------------------------------------------------------------------------------- 1 | What else? 2 | -BinarySearch in Integer Domain. 3 | -BinarySearch in Real Domain. 4 | 5 | Terminology: 6 | Search Space 7 | low 8 | high 9 | median 10 | Check function 11 | 12 | You can solve the problem using BinarySearch if and only if: 13 | - You can design a check function whose domain is the problem's search space 14 | and its range is separated into at most one "False" segment and one "True" segment. 15 | 16 | 17 | Can you design the upper_bound function? 18 | 19 | bool isGreater(int a, int b){ 20 | return a > b; 21 | } 22 | 23 | int upperBound(int *A, int val){ 24 | int lo = 0, med, hi = n-1; 25 | while(lo>1; 27 | if(isGreater(A[med], val)) hi = mid; 28 | else lo = med+1; 29 | } 30 | return lo; 31 | } 32 | 33 | 34 | We have two cases: 35 | 1- Minimization Problems: 36 | -FFFFFFFFFFFFFFFFFFFTTTTTTTTTTTTTTTT 37 | -the range is separated into False-True range. 38 | -the target is the first True 39 | -We ceil the low and floor the median. 40 | 41 | bool ok(int val){ 42 | //Some Checking Statements 43 | } 44 | 45 | int binarySearch(){ 46 | int lo = 0, med, hi = 1000000000; 47 | while(lo>1; 49 | if(ok(A[med])) hi = med; 50 | else lo = med+1; 51 | } 52 | return hi; 53 | } 54 | 55 | 2- Maximization Problems: 56 | -TTTTTTTTTTTTTTTFFFFFFFFFFFFFFF 57 | -the range is separated into True-False range. 58 | -the target is the last True. 59 | -We ceil the median and floor the high. 60 | 61 | bool ok(int val){ 62 | //Some Checking Statements 63 | } 64 | 65 | int binarySearch(){ 66 | int lo = 0, med, hi = 1000000000; 67 | while(lo>1; 69 | if(ok(A[med])) lo = med; 70 | else hi = med-1; 71 | } 72 | return lo; 73 | } 74 | -------------------------------------------------------------------------------- /Built-in functions 01.cpp: -------------------------------------------------------------------------------- 1 | pointers & iterators , begin, end, Lexicographical 2 | count(begin, end, val) //returns number of occurences of val //O(N) 3 | count_if(begin, end, f) //returns number of occurences that satisfy f //O(N) 4 | min_element(begin, end) //returns an iterator //O(N) 5 | max_element(begin, end) //returns an iterator //O(N) 6 | max(val, val) //returns the maximum value 7 | min(val, val) //returns the minimum value 8 | copy(begin1, end1, begin2) //iterator //O(N) 9 | fill(begin, end, val) //O(N) 10 | reverse(begin, end) //~O(N) 11 | sort(begin, end, f) //Ascendignly //O(NLog(N)) 12 | nth_element(begin, nth_element_itr, end) //O(N) 13 | 14 | unique(begin, end) //iterator //O(N) 15 | find(begin, end, val) //iterator //O(N) 16 | binary_search(begin, end, val) //bool //O(Log(N)) 17 | lower_bound(begin, end, val) //iterator >= //O(Log(N)) 18 | upper_bound(begin, end, val) //iterator > //O(Log(N)) 19 | equal_range(begin, end, val) //pair //O(Log(N)) 20 | 21 | next_permutation(begin, end) //bool //O(N) 22 | prev_permutation(begin, end) //bool //O(N) 23 | -------------------------------------------------------------------------------- /Built-in functions 02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int N = 1e3; 6 | int n, A[N]; 7 | 8 | bool fun(int x){ //bool and takes an int parameter 9 | return x%2==0; //returns 1 if x is even 10 | } 11 | 12 | int main(){ 13 | scanf("%d", &n); //read an int 'n' 14 | for(int i = 0 ; i < n ; ++i) 15 | scanf("%d", &A[i]); //read element i of an int array A 16 | 17 | /****************************count & count_if******************************/ 18 | //number of occurences 19 | 20 | printf("Count returned %d\n", count(A, A+n, 1)); //O(N) 21 | printf("Count if returned %d\n", count_if(A, A+n, fun)); //O(N) 22 | 23 | /****************************min_element & max_element******************************/ 24 | 25 | printf("The minimum element is %d\n", *min_element(A, A+n)); //returns an iterator //O(N) 26 | printf("The index of the maximum element is %d\n", max_element(A, A+n) - A); //returns an iterator //O(N) 27 | 28 | /****************************fill******************************/ 29 | //we can use memset if we want to fill an "ARRAY" with 0 or -1 //O(log) 30 | 31 | vector v(10); //vector contains 10 Zeros 32 | fill(v.begin(), v.end(), 3); //now it contains 10 Threes //O(N) 33 | printf("After filling :"); 34 | for(int x : v) 35 | printf("%d ", x); 36 | puts(""); 37 | 38 | /****************************reverse******************************/ 39 | 40 | string str = "Hello world"; 41 | reverse(str.begin(), str.end()); //O(N/2) 42 | printf("Here is the reversed string %s\n", str.c_str()); //stringname.c_str() -> deals with stringname as an char arr 43 | 44 | /****************************sort******************************/ 45 | 46 | sort(A, A+n); //sorts this range Ascendingly //O(Nlog(N)) 47 | printf("The sorted array is : "); 48 | for(int i = 0 ; i < n ; ++i) 49 | printf("%d ", A[i]); 50 | puts(""); 51 | 52 | /****************************copy******************************/ 53 | 54 | int B[N]; 55 | copy(A, A+n, B); 56 | puts("Here are the values in B:"); 57 | for(int i = 0 ; i < n ; ++i) 58 | printf("%d ", B[i]); 59 | puts(""); 60 | 61 | /****************************unique******************************/ 62 | 63 | int last = unique(B, B+n)-B; //last indicates the new size 64 | puts("Array B after using unique:"); 65 | for(int i = 0 ; i < last ; ++i) 66 | printf("%d ", B[i]); 67 | puts(""); 68 | 69 | /****************************binary_search******************************/ 70 | //given a sorted range //O(Log) 71 | 72 | if(binary_search(A, A+n, 5)) //returns 0 | 1 //O(log) 73 | puts("Found"); 74 | else 75 | puts("Not Found"); 76 | 77 | /****************************lower_bound & upper_bound & equal_range******************************/ 78 | //given a sorted range //O(Log) 79 | 80 | printf("Lower bound returned %d\n", *lower_bound(A, A+n, 3)); //an iterator on the first >= 81 | printf("Upper bound returned %d\n", *upper_bound(A, A+n, 3)); //an iterator on the first > 82 | auto itr = equal_range(A, A+n, 3); //pair of iterators ~ lower&upper 83 | printf("The equal range returned %d\n", itr.second-itr.first); 84 | 85 | /****************************next_permutation & prev_permutation******************************/ 86 | //given a lexicographically sorted range makes all the possible permutations 87 | 88 | string text = "Lol"; 89 | sort(text.begin(), text.end()); //Ascendingly 90 | printf("Here is next permutation :D :\n"); 91 | do{ 92 | printf("%s\n", text.c_str()); 93 | }while(next_permutation(text.begin(), text.end())); //each call is in O(N/2) 94 | 95 | //Here the text is sorted again 96 | //you can try it with prev_permutation ;) 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /CSES/Dynamic Programming/cses1158.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int N = 1e3 + 5, M = 1e5 + 2, OO = 0x3f3f3f3f, MOD = 1e9 + 7; 8 | 9 | int n, x; 10 | int H[N], S[N]; 11 | 12 | int dp[2][M]; // availableBooks, remainingMoney 13 | 14 | int solve() { 15 | fill(dp[0], dp[0] + x + 1, 0); 16 | dp[0][0] = dp[1][0] = 0; 17 | 18 | for (int availableBooks = 1; availableBooks <= n; availableBooks++) { 19 | dp[availableBooks & 1][0] = 0; 20 | for (int remainingMoney = 1; remainingMoney <= x; remainingMoney++) { 21 | dp[availableBooks & 1][remainingMoney] = 22 | dp[(availableBooks - 1) & 1][remainingMoney]; 23 | if (remainingMoney >= H[availableBooks]) { 24 | dp[availableBooks & 1][remainingMoney] = 25 | max(dp[availableBooks & 1][remainingMoney], 26 | dp[(availableBooks - 1) & 1][remainingMoney - H[availableBooks]] + S[availableBooks]); 27 | } 28 | } 29 | } 30 | return dp[n&1][x]; 31 | } 32 | 33 | int main() { 34 | scanf("%d %d", &n, &x); 35 | for (int i = 1; i <= n; i++) { 36 | scanf("%d", H + i); 37 | } 38 | for (int i = 1; i <= n; i++) { 39 | scanf("%d", S + i); 40 | } 41 | printf("%d\n", solve()); 42 | return 0; 43 | } -------------------------------------------------------------------------------- /CSES/Dynamic Programming/cses1633.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int N = 1e6+5, MOD = 1e9+7; 6 | 7 | int n; 8 | int dp[N]; 9 | 10 | int main() { 11 | scanf("%d", &n); 12 | dp[0] = 1; 13 | for (int i = 1; i <= n; i++) { 14 | for (int k = 1; k <= 6 && (i - k) >= 0; k++) { 15 | dp[i] = (dp[i] + dp[i-k])%MOD; 16 | } 17 | } 18 | printf("%d\n", dp[n]); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /CSES/Dynamic Programming/cses1634.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int N = 1e2+5, M = 1e6+5, OO = 0x3f3f3f3f; 8 | 9 | int n, x; 10 | int A[N], dp[M]; 11 | 12 | int main() { 13 | scanf("%d %d", &n, &x); 14 | memset(dp, OO, sizeof dp); 15 | for (int i = 0; i < n; i++) { 16 | scanf("%d", A+i); 17 | } 18 | dp[0] = 0; 19 | for (int i = 1; i <= x; i++) { 20 | for (int k = 0; k < n; k++) { 21 | if (i >= A[k]) { 22 | dp[i] = min(dp[i], dp[i-A[k]] + 1); 23 | } 24 | } 25 | } 26 | printf("%d\n", dp[x] == OO ? -1 : dp[x]); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /CSES/Dynamic Programming/cses1635.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int N = 1e2+5, M = 1e6+5, OO = 0x3f3f3f3f, MOD = 1e9+7; 8 | 9 | int n, x; 10 | int A[N], dp[M]; 11 | 12 | int main() { 13 | scanf("%d %d", &n, &x); 14 | for (int i = 0; i < n; i++) { 15 | scanf("%d", A+i); 16 | } 17 | dp[0] = 1; 18 | for (int i = 1; i <= x; i++) { 19 | for (int k = 0; k < n; k++) { 20 | if (i >= A[k]) { 21 | dp[i] = (dp[i] + dp[i - A[k]]) % MOD; 22 | } 23 | } 24 | } 25 | printf("%d\n", dp[x]); 26 | return 0; 27 | } -------------------------------------------------------------------------------- /CSES/Dynamic Programming/cses1636.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int N = 1e2 + 5, M = 1e6 + 5, OO = 0x3f3f3f3f, MOD = 1e9 + 7; 8 | 9 | int n, x; 10 | int A[N], dp[M]; 11 | 12 | int main() { 13 | scanf("%d %d", &n, &x); 14 | for (int i = 0; i < n; i++) { 15 | scanf("%d", A + i); 16 | } 17 | dp[0] = 1; 18 | for (int i = 0; i < n; i++) { 19 | for (int rem = A[i]; rem <= x; rem++) { 20 | dp[rem] += dp[rem - A[i]]; 21 | if (dp[rem] >= MOD) { 22 | dp[rem] -= MOD; 23 | } 24 | } 25 | } 26 | printf("%d\n", dp[x]); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /CSES/Dynamic Programming/cses1637.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int N = 1e6 + 5, OO = 0x3f3f3f3f, MOD = 1e9 + 7; 8 | 9 | int n, cln, d; 10 | int dp[N]; 11 | 12 | int main() { 13 | scanf("%d", &n); 14 | fill(dp, dp+10, 1); 15 | for (int rem = 10; rem <= n; rem++) { 16 | cln = rem; 17 | dp[rem] = OO; 18 | while (cln) { 19 | d = cln % 10; 20 | cln /= 10; 21 | dp[rem] = min(dp[rem], dp[rem - d] + 1); 22 | } 23 | } 24 | printf("%d\n", dp[n]); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /CSES/Dynamic Programming/cses1638.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int N = 1e3+3, MOD = 1e9+7; 6 | 7 | int n; 8 | char A[N][N]; 9 | int dp[N]; 10 | 11 | int main() { 12 | scanf("%d", &n); 13 | for (int r = 0; r < n; r++) { 14 | scanf("%s", A[r]); 15 | } 16 | dp[n-1] = (A[n-1][n-1] == '.'); 17 | for (int r = n-1; ~r; r--) { 18 | for (int c = n-1; ~c; c--) { 19 | if (A[r][c] != '.') { 20 | dp[c] = 0; 21 | continue; 22 | } 23 | dp[c] = (dp[c] + dp[c+1]); 24 | if (dp[c] >= MOD) { 25 | dp[c] -= MOD; 26 | } 27 | } 28 | } 29 | printf("%d\n", dp[0]); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Complexity analysis.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Session : Time Complexity analysis 3 | By : Muhammad Magdi 4 | On : 20/08/2017 5 | */ 6 | 7 | * What's time Complexity? 8 | How does the running time change as the size of input change. 9 | 10 | * Running time depends on: 11 | 1- Processor. 12 | 2- Read/Write speed to memory. 13 | 3- 32 bit VS 64 bit. 14 | 4- INPUT. 15 | 5- ... 16 | 17 | * What are the cases your code may face? 18 | 1- Best case. 19 | 2- Worst case. 20 | 3- Average case. 21 | 22 | * The notations to represent your code's Complexity: 23 | 1- Big O Notation ----> the upper bound of the time. 24 | 2- Omega Notation ----> the lower bound of the time. 25 | 3- Theta Notation ----> the bound itself. 26 | 27 | * Rules: 28 | 1- Running time is the sum of running times of all consecutive blocks. 29 | 2- Nested loops are multiplied. 30 | In general -> Nested repetitive Blocks are multiplied. 31 | 3- In Conditional statements pick the "Worst case" one. 32 | 4- Drop Constants (addition, subtraction, multiplication or division). 33 | 5- Drop all lower order terms. 34 | 35 | 36 | * Some useful Observations: 37 | Big O Name Max n 38 | ------------------------------------------------------------------------------------------- 39 | O(1) ----> Constant ----> 1e18 ----> Math, Observation 40 | O(Log(n)) ----> Logarithmic ----> 1e18 ----> Binary Search (lower -upper- bound) 41 | O(n) ----> Linear ----> 1e8 ----> one loop 42 | O(n*Log(n)) ----> LogLinear ----> 4e5 ----> Sorting, loop + binary search 43 | O(n^2) ----> Quadratic ----> 1e4 ----> nested loop 44 | O(2^n) ----> Exponential ----> 25 ----> Bitmasks, finding all possible answers 45 | O(n!) ----> factorial ----> 11 ----> finding all permutations 46 | 47 | 48 | int calcSum(int a, int b){ //O(1) 49 | int sum = a+b; 50 | return sum; 51 | } 52 | 53 | double calcAverage(int a, int b){ //O(1) 54 | double avg = (a+b)/2.0; 55 | return avg; 56 | } 57 | 58 | bool isAlphabit(char x){ //O(1) 59 | return (x>='A' && x<='Z' || x>='a' && x<='z'); 60 | } 61 | 62 | 63 | 64 | double sumHarmonicSeries(int n){ //O(n) 65 | double sum = 0; 66 | for(int i = 1 ; i <= n ; ++i){ 67 | sum += (1.0/i); 68 | } 69 | return sum; 70 | } 71 | 72 | long long calcSumSegment(int a, int b){ //O(b) 73 | long long sum = 0; 74 | for(int i = a ; i<=b ; ++i) 75 | sum += i; 76 | return sum; 77 | } 78 | 79 | int stepper(int n, int s){ //O(n/s) 80 | int ret = 0; 81 | for(int i = 1 ; i <= n ; i += s){ 82 | ret += i; 83 | } 84 | return ret; 85 | } 86 | 87 | void merge(int* A, int szA, int* B, int szB){ //O(sz) 88 | int idxA = 0, idxB = 0, idxC = 0; 89 | while(idxA < szA && idxB < szB){ 90 | if(A[idxA] < B[idxB]) C[idxC++] = A[idxA++]; 91 | else C[idxC++] = B[idxB++]; 92 | } 93 | while(idxA < szA) C[idxC++] = A[idxA++]; 94 | while(idxB < szB) C[idxC++] = B[idxB++]; 95 | } 96 | 97 | int fact(int n){ //O(n) 98 | if(!n || n==1) return 1; 99 | return n*fact(n-1); 100 | } 101 | 102 | int power1(int base, int power){ //O(power) 103 | if(!power) return 1; 104 | return base*power1(base, power-1); 105 | } 106 | 107 | 108 | int calcLog(int n){ //O(log(n)) 109 | int ret = 0; 110 | while(n > 1){ 111 | ++ret; 112 | n /= 2; 113 | } 114 | return ret; 115 | } 116 | 117 | bool binarySearch(int val, int n){ //O(log(n)) 118 | int lo = 0, hi = n, mid; 119 | while(hi-lo > 0){ 120 | mid = ((lo+hi)>>1); 121 | if(A[mid] == val) return 1; 122 | if(A[mid] < val) 123 | lo = mid+1; 124 | else 125 | hi = mid-1; 126 | } 127 | return 0; 128 | } 129 | 130 | void printPowersOfTwoTill(int n){ //O(log(n)) 131 | for(int p = 1 ; p <= n ; p *= 2) 132 | printf("%d\n", p); 133 | } 134 | 135 | int power2(int base, int power){ //O(log(n)) 136 | if(!power) return 1; 137 | int sub = power2(base, power>>1); 138 | return (power&1? sub*sub*base : sub*sub); 139 | } 140 | 141 | 142 | 143 | for(int i = 0 ; i < (1<>1; 190 | mergeSort(st, mid); 191 | mergeSort(mid+1, en); 192 | merge(A, mid-st+1, A+mid+1, en-mid); 193 | } 194 | 195 | 196 | void printPermutations(string s){ //O(n!) 197 | sort(s.begin(), s.end()); 198 | do { 199 | cout << s << endl; 200 | }while(next_permutation(s.begin(), s.end())); 201 | } 202 | -------------------------------------------------------------------------------- /Cumulative Sum & Frequency Array.txt: -------------------------------------------------------------------------------- 1 | Frequency Array: 2 | -Introduction Problem: 3 | Given n Integers, for each number from 1 to 3 print the number of its occurrences. 4 | ans ----> Three variables. 5 | 6 | -Classical Problem: 7 | Given n<=1e5 Integers ranging from 1 to 1e5,for each given number print the number of its occurrences. 8 | ans1 ----> O(n^2) time. 9 | ans2 ----> O(n) time. 10 | 11 | int x, freq[N] = {0}; 12 | for(int i = 0 ; i < n ; ++i){ 13 | scanf("%d", &x); 14 | freq[x]++; 15 | } 16 | for(int i = 0 ; i < N ; ++i){ 17 | if(freq[i]) 18 | printf("The number %d was found %d times.\n"); 19 | } 20 | 21 | -What if the numbers are Integers in the range 1 to 1e9? 22 | -What if they weren't Integers (e.g. Chars, doubles or Strings)? 23 | 24 | 25 | Cumulative (Prefix) sum: 26 | -Classical Problem: 27 | Given n<=1e5 numbers, and q<=1e5 queries asking about sum of elements from l to r. 28 | ans1 ----> O(n*q) time. 29 | ans2 ----> O(q) time. 30 | 31 | int n, A[N], pre[N], ans, l, r, q; 32 | void prefixSum(){ 33 | scanf("%d", &n); 34 | for(int i = 1 ; i <= n ; ++i){ 35 | scanf("%d", &A[i]); 36 | pre[i] = pre[i-1] + A[i]; 37 | } 38 | scanf("%d", &q); 39 | while(q--){ 40 | scanf("%d%d", &l, &r); 41 | printf("%d\n", pre[r]-pre[l-1]); 42 | } 43 | } 44 | 45 | -What about Suffix sum? 46 | -What about 2D .. what about ND? 47 | 48 | int n, m, A[N][N], pre[N][N], ans, l1, r1, l2, r2, q; 49 | void prefixSum2D(){ 50 | scanf("%d%d", &n, &m); 51 | for(int i = 1 ; i <= n ; ++i){ 52 | for(int j = 1 ; j <= m ; ++j){ 53 | scanf("%d", &A[i][j]); 54 | pre[i][j] = pre[i][j-1] + A[i][j]; 55 | } 56 | for(int j = 1 ; j <= m ; ++j){ 57 | pre[i][j] += pre[i-1][j]; 58 | } 59 | } 60 | scanf("%d", &q); 61 | while(q--){ 62 | scanf("%d%d%d%d", &l1, &r1, &l2, &r2); 63 | printf("%d\n", pre[l2][r2] - pre[l1-1][r2] - pre[l2][r1-1] + pre[l1-1][r1-1]); 64 | } 65 | } 66 | 67 | 68 | Maximum Intersection: 69 | -Classical Problem: 70 | Given n<=1e5 friend who are free from time l to time r<=1e5 71 | , what's the time in which maximum number of friends are free? 72 | ans1 ----> O(n*r) time ----> TLE. 73 | ans2 ----> O(n) time. 74 | 75 | 76 | int q, f, t, day[N], maxi = 0, maxday; 77 | void maximumIntersection(){ 78 | scanf("%d", &q); 79 | while(q--){ 80 | scanf("%d%d", &f, &t); 81 | ++day[l], --day[t+1]; 82 | } 83 | for(int i = 1 ; i <= N ; ++i){ 84 | day[i] += day[i-1]; 85 | if(day[i] > maxi){ 86 | maxi = day[i]; 87 | maxday = i; 88 | } 89 | } 90 | printf("The maximum number of friends is %d in day number %d.\n", maxi, maxday); 91 | } 92 | -------------------------------------------------------------------------------- /DSU.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | const int N = 1e5+5 , M = (1<<14), OO = 0x3f3f3f3f; 6 | 7 | int n, q; 8 | int t, a, b; 9 | 10 | int parent[N]; 11 | inline void init(){ 12 | iota(parent, parent+N, 0); 13 | } 14 | 15 | int findParent(int x){ 16 | if(parent[x] == x) return x; 17 | return parent[x] = findParent(parent[x]); 18 | } 19 | 20 | inline bool sameSet(int a, int b){ 21 | return findParent(a) == findParent(b); 22 | } 23 | 24 | inline void merge(int a, int b){ 25 | a = findParent(a), b = findParent(b); 26 | if(a == b) return; 27 | parent[b] = a; 28 | } 29 | 30 | 31 | int main(){ 32 | scanf("%d %d", &n, &q); 33 | init(); 34 | while(q--){ 35 | scanf("%d %d %d", &t, &a, &b); 36 | if(t){ //Make Friends 37 | merge(a, b); 38 | }else{ //Are Friends? 39 | printf("%d\n", sameSet(a, b)); 40 | } 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Dynamic Programming/CoinChange.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = (1<<20) , M = (1<<16), OO = 0x3f3f3f3f; 5 | 6 | int n; 7 | int Coins[] = {5, 10, 25, 50, 100}; 8 | long long mem[5][N]; 9 | 10 | long long solve(int i = 0, int rem = n){ //O(n*n) 11 | if(i==5) return rem == 0; 12 | long long& ret = mem[i][rem]; 13 | if(~ret) return ret; 14 | return ret = (rem>=Coins[i]? solve(i, rem-Coins[i]) : 0) + solve(i+1, rem); 15 | } 16 | 17 | int main(){ 18 | memset(mem, -1, sizeof mem); 19 | scanf("%d", &n); 20 | printf("%lld\n", solve()); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Dynamic Programming/Knapsack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = (1<<10) , M = (1<<16), OO = 0x3f3f3f3f; 5 | 6 | int n, W[N], C[N], k; 7 | int mem[N][N]; //O(n*k) 8 | 9 | int KS(int i = 0, int rem = k){ //O(n*k) 10 | if(i == n) return 0; 11 | int & ret = mem[i][rem]; 12 | if(~ret) return ret; 13 | return ret = max(rem>=W[i]? KS(i+1, rem-W[i])+C[i] : -OO, KS(i+1, rem)); 14 | } 15 | 16 | int main(){ 17 | // freopen("i.in", "rt", stdin); 18 | // freopen("o.out", "wt", stdout); 19 | scanf("%d %d", &n, &k); 20 | memset(mem, -1, sizeof mem); 21 | for(int i = 0 ; i < n ; ++i) 22 | scanf("%d %d", W+i, C+i); 23 | printf("%d\n", KS()); 24 | return 0; 25 | } 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Dynamic Programming/LIS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef long long ll; 4 | using namespace std; 5 | 6 | const int N = 1e3 + 2, M = 1e4+5, OO = 0x3f3f3f3f; 7 | 8 | int n, A[N]; 9 | int mem[N][N]; 10 | 11 | int solve(int i = 0, int prev = n){ //Memory -> O(n^2), Time -> O(n^2) 12 | if(i == n) return 0; 13 | int& ret = mem[i][prev]; 14 | if(~ret) return ret; 15 | return ret = max(solve(i+1, prev), (A[i]>A[prev]? solve(i+1, i)+1 : 0)); 16 | } 17 | 18 | int main(){ 19 | scanf("%d", &n); 20 | for(int i = 0 ; i < n ; ++i) scanf("%d", A+i); 21 | memset(mem, -1, sizeof mem); 22 | printf("%d\n", solve()); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Dynamic Programming/Longest Common Subsequence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = (1<<11) , M = (1<<14), OO = 0x3f3f3f3f; 5 | 6 | int mem[N][N]; 7 | int n, m; 8 | string s1, s2; 9 | 10 | int LCS(int i = 0, int j = 0){ 11 | if(i==n || j == m) return 0; 12 | if(~mem[i][j]) return mem[i][j]; 13 | if(s1[i] == s2[j]) 14 | return mem[i][j] = LCS(i+1, j+1)+1; 15 | return mem[i][j] = max(LCS(i+1, j), LCS(i, j+1)); 16 | } 17 | 18 | int main(){ 19 | // freopen("i.in", "rt", stdin); 20 | // freopen("o.out", "wt", stdout); 21 | cin >> s1 >> s2; 22 | memset(mem, -1, sizeof mem); 23 | n = s1.length(); 24 | m = s2.length(); 25 | printf("%d\n", LCS()); 26 | return 0; 27 | } 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Dynamic Programming/MCM.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef long long ll; 4 | using namespace std; 5 | 6 | const int N = 1e2 + 5, M = 1e3+5, OO = 0x3f3f3f3f, mod = 1e9+7; 7 | 8 | int n, R[N], C[N]; 9 | 10 | ll mem[N][N]; 11 | ll solve(int i = 0, int j = n-1){ 12 | if(i == j) return 0; 13 | ll& ret = mem[i][j]; 14 | if(~ret) return ret; 15 | ret = OO*1ll*OO; 16 | for(int m = i ; m < j ; ++m) 17 | ret = min(ret, solve(i, m)+solve(m+1, j)+R[i]*C[j]*C[m]); 18 | return ret; 19 | } 20 | 21 | int main(){ 22 | scanf("%d", &n); 23 | for(int i = 0 ; i < n ; ++i) scanf("%d %d", R+i, C+i); 24 | memset(mem, -1, sizeof mem); 25 | solve(); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Dynamic Programming/MaximumPathSum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = (1<<10) , M = (1<<16), OO = 0x3f3f3f3f; 5 | 6 | int n, m, A[N][N]; 7 | int mem[N][N]; 8 | 9 | int maximumPathSum(int i=0, int j=0){ 10 | if(i==n-1 && j==m-1) return 0; 11 | int & ret = mem[i][j]; 12 | if(ret != OO) return ret; 13 | return ret=max(i+1 2 | 3 | using namespace std; 4 | const int N = (1<<11) , M = (1<<14), OO = 0x3f3f3f3f; 5 | 6 | int mem[N][N]; 7 | int n, m; 8 | string s1, s2; 9 | 10 | int MED(int i = 0, int j = 0){ 11 | if(i==n) return m-j; 12 | if(j==m) return n-i; 13 | if(~mem[i][j]) return mem[i][j]; 14 | if(s1[i] == s2[j]) return mem[i][j] = MED(i+1, j+1); 15 | return mem[i][j] = min(MED(i+1, j), min(MED(i, j+1), MED(i+1, j+1)))+1; 16 | } 17 | 18 | int main(){ 19 | // freopen("i.in", "rt", stdin); 20 | // freopen("o.out", "wt", stdout); 21 | cin >> s1 >> s2; 22 | memset(mem, -1, sizeof mem); 23 | n = s1.length(); 24 | m = s2.length(); 25 | printf("%d\n", MED()); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Dynamic Programming/TSP.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize ("O3") 2 | #include 3 | 4 | using namespace std; 5 | const int N = 18 , M = (1<<14), OO = 0x3f3f3f3f; 6 | 7 | int src; 8 | int n, m; 9 | int adj[N][N]; 10 | int mem[N][1< 2 | #include 3 | 4 | using namespace std; 5 | const int N = 5e4 + 5, M = 1e5+5, OO = 0x3f3f3f3f; 6 | 7 | int ne, head[N], nxt[M], to[M]; 8 | int n, m, u, v; 9 | 10 | void init(){ 11 | memset(head, -1, n*sizeof head[0]); 12 | ne = 0; 13 | } 14 | 15 | void addEdge(int f, int t){ 16 | nxt[ne] = head[f]; 17 | to[ne] = t; 18 | head[f] = ne++; 19 | } 20 | 21 | void addBiEdge(int a, int b){ 22 | addEdge(a, b); 23 | addEdge(b, a); 24 | } 25 | 26 | 27 | int main(){ 28 | scanf("%d %d", &n, &m); 29 | init(); 30 | for(int i = 0 ; i < m ; ++i){ 31 | scanf("%d %d", &u, &v); 32 | addBiEdge(u, v); 33 | } 34 | for(int u = 0 ; u < n ; ++u){ 35 | printf("Neighbours of %d are:", u); 36 | for(int k = head[u] ; ~k ; k = nxt[k]){ 37 | int v = to[k]; 38 | printf(" %d", v); 39 | } 40 | puts(""); 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Graphs/AdjacencyList[Vector].cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | const int N = 5e4 + 5, M = 1e5+5, OO = 0x3f3f3f3f; 6 | 7 | int n, m, u, v; 8 | vector adj[N]; 9 | 10 | int main(){ 11 | scanf("%d %d", &n, &m); 12 | for(int i = 0 ; i < m ; ++i){ 13 | scanf("%d %d", &u, &v); 14 | adj[u].push_back(v); 15 | adj[v].push_back(u); 16 | } 17 | for(int u = 0 ; u < n ; ++u){ 18 | printf("Neighbours of %d are:", u); 19 | for(int v : adj[u]){ 20 | printf(" %d", v); 21 | } 22 | puts(""); 23 | } 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Graphs/Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int N = (1<<22), M = (1<<18), OO = 0x3f3f3f3f; 6 | 7 | vector > adj[N]; 8 | int n, m, u, v, c, s; 9 | int dis[N]; 10 | 11 | void Dijkstra(int src){ 12 | // priority_queue, vector>, greater>> pq; 13 | priority_queue> pq; 14 | pq.push({0, src}); 15 | dis[src] = 0; 16 | while(!pq.empty()){ 17 | int p = pq.top().second; 18 | int d = -pq.top().first; 19 | pq.pop(); 20 | if(d > dis[p]) continue; 21 | for(pair ch : adj[p]){ 22 | if(dis[ch.second] > d+ch.first){ 23 | dis[ch.second] = d+ch.first; 24 | pq.push(make_pair(-dis[ch.second], ch.second)); 25 | } 26 | } 27 | } 28 | } 29 | 30 | int main() { 31 | scanf("%d %d", &n, &m); 32 | for(int i = 0 ; i < m ; ++i){ 33 | scanf("%d %d %d", &u, &v, &c); 34 | adj[u].push_back({c, v}); 35 | adj[v].push_back({c, u}); 36 | } 37 | memset(dis, OO, sizeof dis); 38 | scanf("%d", &s); 39 | Dijkstra(s); 40 | for(int i = 1 ; i <= n ; ++i){ 41 | printf("Shortest path from %d to %d is %d\n", s, i, dis[i]); 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /Graphs/FloodFill.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e3 + 5, OO = 0x3f3f3f3f, MOD = 1000000007; 5 | const double EPS = 0.000000001; 6 | 7 | int n, m, rx, ry, cx, cy; 8 | string grid[N]; 9 | int dis[N][N]; 10 | int dx[] = {1, -1, 0, 0}; //Four Dimensions 11 | int dy[] = {0, 0, 1, -1}; 12 | 13 | bool valid(int x, int y){ //All the conditions required to visit this node 14 | return (x>=0 && y>=0 && x > q; 19 | q.push({ratx, raty}); 20 | dis[ratx][raty] = 0; 21 | while(!q.empty()){ 22 | int parentx = q.front().first, parenty = q.front().second; 23 | q.pop(); 24 | for(int i = 0 ; i < 4 ; ++i){ 25 | int childx = parentx+dx[i], childy=parenty+dy[i]; 26 | if(!valid(childx, childy)) continue; 27 | dis[childx][childy] = dis[parentx][parenty] + 1; 28 | q.push({childx, childy}); 29 | } 30 | } 31 | } 32 | 33 | int main(){ 34 | //freopen("i.in", "rt", stdin); 35 | //freopen("o.out", "wt", stdout); 36 | cin.sync_with_stdio(0); 37 | memset(dis, OO, sizeof dis); 38 | cin >> n >> m; 39 | for(int i = 0 ; i < n ; ++i) 40 | cin >> grid[i]; 41 | for(int i = 0 ; i < n ; ++i){ 42 | for(int j = 0 ; j < m ; ++j){ 43 | if(grid[i][j] == 'R') rx = i, ry = j; 44 | else if(grid[i][j] == 'C') cx = i, cy = j; 45 | } 46 | } 47 | BFS(rx, ry); 48 | if(dis[cx][cy]==OO) 49 | puts("The Cheese isn't reachable"); 50 | else 51 | printf("The shortest Path from Rat to Cheese is %d steps.\n", dis[cx][cy]); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Graphs/Floyd.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int N = (1<<9), M = (1<<18), OO = 0x3f3f3f3f; 6 | 7 | int adj[N][N]; 8 | int n, m, u, v, c; 9 | 10 | int main() { 11 | scanf("%d %d", &n, &m); 12 | memset(adj, OO, sizeof adj); 13 | for(int i = 0 ; i < m ; ++i){ 14 | scanf("%d %d %d", &u, &v, &c); 15 | adj[u][v] = c; 16 | } 17 | for(int k = 1 ; k <= n ; ++k) 18 | for(int i = 1 ; i <= n ; ++i) 19 | for(int j = 1 ; j <= n ; ++j) 20 | adj[i][j] = min(adj[i][j], adj[i][k]+adj[k][j]); 21 | for(int i = 1 ; i <= n ; ++i){ 22 | for(int j = 1 ; j <= n ; ++j){ 23 | printf("%10d%c", adj[i][j], " \n"[j==n]); 24 | } 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Graphs/Graph Representation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = (1<<10) , M = 2e3 + 5, OO = 0x3f3f3f3f; 5 | const double EPS = 0.0000001, PI = 2*acos(0.0); 6 | 7 | vector > edgelist; //unweighted edge list 8 | vector > wEdgeList; //weighted edge list 9 | 10 | bool adjMat[N][N]; //unweighted adjacency matrix 11 | int wAdjMat[N][N]; //weighted adjacency matrix 12 | 13 | vector adjList[N]; //unweighted adjacency list 14 | vector > wAdjList[N]; //weighted adjacency list 15 | 16 | int n, m, u, v, c; 17 | 18 | int main(){ 19 | // freopen("i.in", "rt", stdin); 20 | // freopen("o.out", "wt", stdout); 21 | cin.sync_with_stdio(0); 22 | cin >> n >> m; 23 | for(int i = 0 ; i < m ; ++i){ //number of edges 24 | cin >> u >> v; // from, to 25 | adj1[u].push_back(v); 26 | adj1[v].push_back(u); //for undirected graphs 27 | 28 | /* in a weighted graph 29 | cin >> u >> v >> c; 30 | adj2[u].push_back({c, v}); 31 | adj2[v].push_back({c, u}); 32 | */ 33 | 34 | /* or using adjacency matrix 35 | adj3[u][v] = c; 36 | adj3[v][u] = c; 37 | */ 38 | } 39 | return 0; 40 | } 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Graphs/Is DAG.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e5 + 5, OO = 0x3f3f3f3f; 5 | const double EPS = 0.000000001; 6 | 7 | int n, m, u, v, x, maxi, first, IsDAG = 1; 8 | vector adj[N]; 9 | int vis[N]; 10 | 11 | void DFS(int p){ //p = parent 12 | vis[p] = 2; //In Stack 13 | for(int ch : adj[p]){ //ch = child 14 | if(vis[ch] == 2) IsDAG = 0; //Here's a cycle 15 | if(!vis[ch]) DFS(ch); //Recurse 16 | } 17 | vis[p] = 1; //Visited 18 | } 19 | 20 | int main(){ 21 | //freopen("i.in", "rt", stdin); 22 | //freopen("o.out", "wt", stdout); 23 | cin.sync_with_stdio(0); 24 | cin >> n >> m; 25 | for(int i = 0 ; i < m ; ++i){ 26 | cin >> u >> v; 27 | adj[u].push_back(v); 28 | } 29 | for(int i = 1 ; i <= n ; ++i){ //-try to-Traverse starting from each non-visited node 30 | if(!vis[i]) DFS(i); 31 | } 32 | puts(IsDAG? "DAG" : "NOT a DAG"); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Graphs/Minimum Spanning Tree [Kruskal].cpp: -------------------------------------------------------------------------------- 1 | //Spoj CSTREET 2 | #include 3 | 4 | using namespace std; 5 | 6 | const int N = 1e3+5, M = 3e5+5, OO = 0x3f3f3f3f; 7 | 8 | struct edge{ 9 | int f, t, c; 10 | bool operator <(const edge& e)const{ 11 | return c < e.c; 12 | } 13 | }E[M]; 14 | int sorted[M]; 15 | 16 | int t, p, n, m, u, v, c, total; 17 | 18 | int par[N]; 19 | inline void init(){ 20 | iota(par, par+n, 0); 21 | } 22 | 23 | inline int find(int u){ 24 | return par[u] == u ? u : par[u] = find(par[u]); 25 | } 26 | 27 | inline bool sameSet(int a, int b){ 28 | return find(a) == find(b); 29 | } 30 | 31 | inline void join(int a, int b){ 32 | a = find(a), b = find(b); 33 | if(a == b) return; 34 | par[a] = b; 35 | } 36 | 37 | int main(){ 38 | scanf("%d", &t); 39 | while(t--){ 40 | scanf("%d %d %d", &p, &n, &m); 41 | init(); 42 | for(int i = 0 ; i < m ; ++i){ 43 | scanf("%d %d %d", &u, &v, &c); 44 | E[i] = {--u, --v, c}; 45 | sorted[i] = i; 46 | } 47 | sort(sorted, sorted+m, [](const int& a, const int& b){ 48 | return E[a] < E[b]; 49 | }); 50 | total = 0; 51 | for(int i = 0 ; i < m ; ++i){ 52 | int idx = sorted[i]; 53 | if(!sameSet(E[idx].f, E[idx].t)){ 54 | join(E[idx].f, E[idx].t); 55 | total += E[idx].c; 56 | } 57 | } 58 | printf("%d\n", p*total); 59 | } 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /Graphs/Number Of Connected Components.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e5 + 5, OO = 0x3f3f3f3f; 5 | const double EPS = 0.000000001; 6 | 7 | int n, m, u, v, num; 8 | vector adj[N]; 9 | bool vis[N]; 10 | 11 | void DFS(int p){ 12 | vis[p] = 1; 13 | for(int ch : adj[p]) 14 | if(!vis[ch]) DFS(ch); 15 | } 16 | 17 | int main(){ 18 | //freopen("i.in", "rt", stdin); 19 | //freopen("o.out", "wt", stdout); 20 | cin.sync_with_stdio(0); 21 | cin >> n >> m; 22 | for(int i = 0 ; i < m ; ++i){ 23 | cin >> u >> v; 24 | adj[u].push_back(v); 25 | adj[v].push_back(u); 26 | } 27 | for(int i = 1 ; i <= n ; ++i){ 28 | if(!vis[i]) DFS(i), ++num; 29 | } 30 | printf("%d\n", num); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Graphs/SSSP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e4 + 5, OO = 0x3f3f3f3f, MOD = 1000000007; 5 | const double EPS = 0.000000001; 6 | 7 | int n, m, a, b, x; 8 | vector adj[N]; 9 | int dis[N]; 10 | 11 | void BFS(int src){ 12 | queue q; 13 | q.push(src); 14 | dis[src] = 0; 15 | while(!q.empty()){ 16 | int p = q.front(); 17 | q.pop(); 18 | for(int ch : adj[p])if(dis[ch]==OO){ 19 | dis[ch] = dis[p]+1; 20 | q.push(ch); 21 | } 22 | } 23 | } 24 | 25 | int main(){ 26 | //freopen("i.in", "rt", stdin); 27 | //freopen("o.out", "wt", stdout); 28 | cin.sync_with_stdio(0); 29 | int n, m; 30 | cin >> n >> m; 31 | for(int i = 0 ; i < m ; ++i){ 32 | cin >> a >> b; 33 | adj[a].push_back(b); 34 | adj[b].push_back(a); 35 | } 36 | cin >> x; 37 | memset(dis, OO, sizeof dis); 38 | BFS(x); 39 | for(int i = 1 ; i <= n ; ++i) 40 | printf("The Shortest Path between %d and %d is %d\n", x, i, dis[i]); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /Graphs/Topological ordering.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e5 + 5, OO = 0x3f3f3f3f; 5 | const double EPS = 0.000000001; 6 | 7 | int n, m, u, v; 8 | vector adj[N]; 9 | bool vis[N]; 10 | 11 | /* 12 | void DFS(int p){ //iterative DFS 13 | stack st; 14 | st.push(p); 15 | vis[p] = 1; 16 | while(!st.empty()){ 17 | int p = st.top(); 18 | st.pop(); 19 | for(int ch : adj[p]){ 20 | if(!vis[ch]) st.push(ch); 21 | vis[ch] = 1; 22 | } 23 | } 24 | } 25 | */ 26 | 27 | void DFS(int p){ //topological ordering 28 | vis[p] = 1; 29 | for(int ch : adj[p]) //Finish all the dependencies 30 | if(!vis[ch]) DFS(ch); //.., 31 | printf("%d ", p); //then print me 32 | } 33 | 34 | 35 | int main(){ 36 | //freopen("i.in", "rt", stdin); 37 | //freopen("o.out", "wt", stdout); 38 | cin.sync_with_stdio(0); 39 | cin >> n >> m; 40 | for(int i = 0 ; i < m ; ++i){ 41 | cin >> u >> v; 42 | adj[v].push_back(u); //Reverse edges 43 | } 44 | for(int i = 1 ; i <= n ; ++i){ //-try to-Traverse starting from each non-visited node 45 | if(!vis[i]) DFS(i); 46 | } 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Graphs/isBipartite.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e3 + 5, OO = 0x3f3f3f3f, MOD = 1000000007; 5 | const double EPS = 0.000000001; 6 | 7 | int n, m, a, b; 8 | vector adj[N]; 9 | int col[N]; 10 | 11 | bool BFS(int src){ 12 | queue q; 13 | q.push(src); 14 | col[src] = 0; //Give it some color 15 | while(!q.empty()){ 16 | int p = q.front(); 17 | q.pop(); 18 | for(int ch : adj[p]){ 19 | if(col[ch] == OO){ //If my child isn't colored 20 | col[ch] = !col[p]; //give him NOT my color 21 | q.push(ch); 22 | }else if(col[ch]==col[p]){ //if my child's color is the same as mine 23 | return 0; //so, it can't be a bipartite -bicolorable- graph 24 | } 25 | } 26 | } 27 | return 1; //It can be Bipartite 28 | } 29 | 30 | int main(){ 31 | //freopen("i.in", "rt", stdin); 32 | //freopen("o.out", "wt", stdout); 33 | cin.sync_with_stdio(0); 34 | memset(col, OO, sizeof col); 35 | cin >> n >> m; 36 | for(int i = 0 ; i < m ; ++i){ 37 | cin >> a >> b; 38 | adj[a].push_back(b); 39 | adj[b].push_back(a); 40 | } 41 | for(int i = 1 ; i <= n ; ++i){ 42 | if(col[i]==OO){ //BFS from each non-visited node 43 | if(!BFS(i)){ 44 | printf("Not BiPartite\n"); 45 | return 0; 46 | } 47 | } 48 | } 49 | puts("Bipartite"); 50 | return 0; 51 | } 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /Kadane Algorithm/1D-Kadane.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e6 + 5, OO = 0x3f3f3f3f, MOD = 1000000007; 5 | const double EPS = 0.000000001; 6 | 7 | int n; 8 | int A[N]; 9 | long long sum, bestSum; 10 | 11 | int main(){ 12 | //freopen("i.in", "rt", stdin); 13 | //freopen("o.out", "wt", stdout); 14 | scanf("%d", &n); 15 | for(int i = 0 ; i < n ; ++i) 16 | scanf("%d", A+i); 17 | for(int i = 0 ; i < n ; ++i){ 18 | sum += A[i]; 19 | sum = max(sum, 0ll); 20 | bestSum = max(bestSum, sum); 21 | } 22 | printf("%lld\n", bestSum); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Kadane Algorithm/2D-Kadane.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e2 + 5, OO = 0x3f3f3f3f, MOD = 1000000007; 5 | const double EPS = 0.000000001; 6 | 7 | int n, m; 8 | int A[N][N]; 9 | long long bestSum; 10 | 11 | int main(){ 12 | //freopen("i.in", "rt", stdin); 13 | //freopen("o.out", "wt", stdout); 14 | scanf("%d %d", &n, &m); 15 | for(int i = 1 ; i <= n ; ++i){ 16 | for(int j = 1 ; j <= m ; ++j){ 17 | scanf("%d", A[i]+j); 18 | A[i][j] += A[i-1][j]; //Cummulative Columns. 19 | } 20 | } 21 | for(int top = 1 ; top <= n ; ++top){ 22 | for(int btm = top ; btm <= n ; ++btm){ 23 | long long sum = 0; 24 | for(int i = 1 ; i <= m ; ++i){ 25 | sum += A[btm][i] - A[top-1][i]; //Add current element -Column- 26 | sum = max(sum, 0ll); //Does it worth? 27 | bestSum = max(bestSum, sum); //Is it the best? 28 | } 29 | } 30 | } 31 | printf("%lld\n", bestSum); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Kadane Algorithm/3D-Kadane.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 22 , OO = 0x3f3f3f3f, MOD = 1000000007; 5 | const double EPS = 0.000000001; 6 | 7 | int a, b, c; 8 | long long A[N][N][N]; 9 | long long bestSum; 10 | 11 | int main(){ 12 | //freopen("i.in", "rt", stdin); 13 | //freopen("o.out", "wt", stdout); 14 | scanf("%d %d %d", &a, &b, &c); 15 | for(int i = 1 ; i <= a ; ++i){ 16 | for(int j = 1 ; j <= b ; ++j){ 17 | for(int k = 1 ; k <= c ; ++k){ 18 | scanf("%lld", A[i][j]+k); 19 | A[i][j][k] += A[i-1][j][k] + A[i][j-1][k] - A[i-1][j-1][k]; //Cummulative grids 20 | } 21 | } 22 | } 23 | for(int sa = 1 ; sa <= a ; ++sa)for(int ea = sa ; ea <= a ; ++ea){ 24 | for(int sb = 1 ; sb <= b ; ++sb)for(int eb = sb ; eb <= b ; ++eb){ 25 | long long sum = 0; 26 | for(int i = 1 ; i <= c ; ++i){ 27 | sum += A[ea][eb][i] - A[sa-1][eb][i] - A[ea][sb-1][i] + A[sa-1][sb-1][i]; 28 | sum = max(sum, 0ll); //Does it worth? 29 | bestSum = max(bestSum, sum); //Is it the best? 30 | } 31 | } 32 | } 33 | printf("%lld\n", bestSum); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Muhammad Magdi 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 | -------------------------------------------------------------------------------- /LIS.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Different Solutions for LIS Problem 3 | Muhammad Magdi 4 | */ 5 | #include 6 | 7 | using namespace std; 8 | const int N = 1000, M = 2e6, OO = 1000000007; 9 | const double EPS = 0.00000001; 10 | 11 | int n , A[N+9], mem[N+9][N+9]; 12 | 13 | /********************* Recursive DP Solution *********************/ 14 | 15 | int LIS(int i = 0, int prev = n){ //Memory -> O(n^2), Time -> O(n^2) 16 | if(i == n) return mem[i][prev] = 0; 17 | int &ret = mem[i][prev]; 18 | if(~ret) return ret; 19 | return ret = max(LIS(i+1, prev), (A[i]>A[prev]? LIS(i+1, i)+1 : 0)); 20 | } 21 | 22 | void buildLIS(int i = 0, int prev = n){ 23 | if(i==n) return; 24 | if(~mem[i+1][prev] && mem[i][prev] == mem[i+1][prev]) //we left it 25 | buildLIS(i+1, prev); 26 | else if(~mem[i+1][i] && mem[i][prev] == mem[i+1][i]+1){ //we took it 27 | printf("%d ", A[i]); 28 | buildLIS(i+1, i); 29 | } 30 | } 31 | 32 | /********************* Iterative DP Solution *********************/ 33 | 34 | int dp[N+9][N+9]; 35 | int iterativeLIS(){ //Memory -> O(n^2), Time -> O(n^2) 36 | for(int i = 0 ; i <= n ; ++i) 37 | dp[n][i] = 0; 38 | for(int i = n-1 ; ~i ; --i) 39 | for(int prev = n ; ~prev ; --prev) 40 | dp[i][prev] = max(dp[i+1][prev], ((prev == n || A[i]>A[prev])? dp[i+1][i]+1 : 0)); 41 | return dp[0][n]; 42 | } 43 | 44 | int rdp[2][N+9]; 45 | int rollingLIS(){ //Memory -> O(n), Time -> O(n^2) 46 | int r = 0; 47 | for(int i = 0 ; i <= n ; ++i) //Base Case 48 | rdp[r][i] = rdp[!r][i] = 0; 49 | for(int i = n-1 ; ~i ; --i){ //Bottom-Up Approach 50 | r = !r; //switch to the other row 51 | for(int prev = n ; ~prev ; --prev) 52 | rdp[r][prev] = max(rdp[!r][prev], ((prev == n || A[i]>A[prev])? rdp[r][i]+1 : 0)); 53 | } 54 | return rdp[r][n]; 55 | } 56 | 57 | /********************* BinarySearch Solution *********************/ 58 | 59 | int binarySearchLIS(){ //Memory -> O(n), Time -> O(nLogn) 60 | vector ret; 61 | for(int i=0; i O(n), Time -> O(nLogn) 70 | int LIS = 0, ret[N+9] , last = -1; 71 | set retset[N+9]; 72 | for(int i=0; i>1) 93 | 94 | int st[N<<2]; 95 | 96 | void update(int p, int l, int r, int idx, int val){ 97 | if(l>r || l>idx || rr || l>j || r=i && r<=j) return st[p]; 109 | int q1 = getMax(lft(p), l, med(l, r), i, j); 110 | int q2 = getMax(rit(p), med(l, r)+1, r, i, j); 111 | return max(q1, q2); 112 | } 113 | 114 | bool cmp(pair &a, pair & b){ 115 | //ascending values then descending indices to get LIS 116 | if(a.first == b.first) return a.second>b.second; 117 | return a.first < b.first; 118 | } 119 | 120 | void segmentTreeLIS(){ //Memory -> O(n), Time -> O(nLogn) 121 | pair arr[n+5]; //pair of value and index 122 | for(int i = 0 ; i < n ; ++i) 123 | arr[i] = {A[i], i}; 124 | sort(arr, arr+n, cmp); 125 | for(int i = 0 ; i < n ; ++i){ 126 | int beforeMe = getMax(1, 0, n-1, 0, arr[i].second); 127 | update(1, 0, n-1, arr[i].second, beforeMe+1); 128 | } 129 | printf("Segment Tree says that LIS = %d\n", st[1]); 130 | } 131 | 132 | /********************* main function *********************/ 133 | 134 | int main(){ 135 | // freopen("i.in", "r", stdin); 136 | // freopen("o.out", "w", stdout); 137 | memset(mem, -1, sizeof mem); 138 | scanf("%d", &n); 139 | for(int i = 0 ; i < n ; ++i) 140 | scanf("%d", A+i); 141 | printf("Recursive Solution says LIS = %d\n", LIS()); 142 | printf("And a valid sub-sequence is : "); 143 | buildLIS(); 144 | puts(""); 145 | printf("Iterative Solution says LIS = %d\n", iterativeLIS()); 146 | printf("With Rolling the answer is %d\n", LIS()); 147 | binarySearchLISWithBuilding(); 148 | segmentTreeLIS(); 149 | return 0; 150 | } 151 | 152 | /* input samples 153 | 5 154 | 1 4 2 4 3 155 | 156 | 6 157 | 2 4 3 4 1 6 158 | */ 159 | -------------------------------------------------------------------------------- /Matrices.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | typedef long long ll; 8 | 9 | #define row vector 10 | #define matrix vector 11 | #define ROWS(v) (v).size() 12 | #define COLS(v) (v)[0].size() 13 | 14 | const int N = 5e4+5, OO = 0x3f3f3f3f, MOD = 1e9+7; 15 | 16 | inline ll fixMod(ll a, ll m){ 17 | return (a%m+m)%m; 18 | } 19 | 20 | void printMatrix(const matrix& m){ 21 | for(auto r : m){ 22 | for(auto x : r){ 23 | cout << x << " "; 24 | } 25 | cout << endl; 26 | } 27 | } 28 | 29 | matrix identity(int n){ 30 | matrix ret(n ,row(n, 0)); 31 | for(int i = 0 ; i < n ; ++i) ret[i][i] = 1; 32 | return ret; 33 | } 34 | 35 | matrix add(const matrix& a, const matrix& b){ 36 | matrix ret(ROWS(a), row(COLS(a), 0)); 37 | for(int i = 0 ; i < ROWS(a) ; ++i) 38 | for(int j = 0 ; i < COLS(a) ; ++j) 39 | ret[i][j] = a[i][j] + b[i][j]; 40 | return ret; 41 | } 42 | 43 | matrix multiply(const matrix& a, const matrix& b){ 44 | matrix ret(ROWS(a), row(COLS(b), 0)); 45 | for(int r = 0 ; r < ROWS(a) ; ++r) 46 | for(int k = 0 ; k < COLS(a) ; ++k) 47 | if(a[r][k])for(int c = 0 ; c < COLS(b) ; ++c) 48 | ret[r][c] = (ret[r][c] + (a[r][k]*b[k][c])%MOD)%MOD; 49 | return ret; 50 | } 51 | 52 | matrix power(const matrix& a, ll p){ 53 | if(!p) return identity(ROWS(a)); 54 | matrix m = power(a, p>>1); 55 | m = multiply(m, m); 56 | if(p&1) m = multiply(m, a); 57 | return m; 58 | } 59 | 60 | matrix powerI(const matrix& a, ll p){ 61 | matrix ret = identity(ROWS(a)), t = a; 62 | while(p){ 63 | if(p&1) ret = multiply(ret, t); 64 | t = multiply(t, t); 65 | p >>= 1; 66 | } 67 | return ret; 68 | } 69 | 70 | int main(){ 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /Number Theory/Number Theory 01.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Session : Number Theory 3 | By : Muhammad Magdi 4 | On : 28/09/2017 5 | */ 6 | 7 | What to know? 8 | -Multiples -> All the numbers that are divisible by some Integer. 9 | -Divisors -> All the numbers that divide some Integer. 10 | -Primes -> A Number which is divisible only by 1 and itself. 11 | -Factors -> The prime numbers that divide an Integer exactly. 12 | -Modular Arithmetic. 13 | -Fast Powering. 14 | -GCD(a, b) -> The greatest number that divides both 'a' and 'b'. 15 | -LCM(a, b) -> The smallest number that's divisible by both 'a' and 'b'. 16 | 17 | /********************************* Multiples ***************************************/ 18 | 19 | Problem #1 -> Given an integer 'n' find all of its Multiples that are less than 'N'. 20 | 21 | for(int i = 2*n ; i < N ; i+=n){ //note the assignment statement 22 | printf("%d ", i); 23 | } 24 | 25 | /******************************** Divisors ****************************************/ 26 | 27 | Problem #2 -> Given an integer 'n' find all of its Divisors. 28 | Solution #1: 29 | "Iterate through all numbers from 1 to n and check its divisibility" 30 | 31 | vector v; 32 | void findDivisors1(int n){ //O(N) 33 | for(int i = 1 ; i <= n ; ++i){ 34 | if(n%i == 0) v.push_back(i); 35 | } 36 | } 37 | 38 | Example -> n = 36 39 | 36 / 1 = 36 40 | 36 / 2 = 18 41 | 36 / 3 = 12 42 | 36 / 4 = 9 43 | 36 / 6 = 6 44 | 36 / 9 = 4 45 | 36 / 12 = 3 46 | 36 / 18 = 2 47 | 36 / 36 = 1 48 | Can you find any Observation? 49 | -Square root :D 50 | 51 | set st; 52 | void findDivisors2(int n){ //O(sqrt(N)*log(n)) 53 | for(int i = 1 ; i*i <= n ; ++i){ //O(sqrt(n)) 54 | if(n%i == 0){ 55 | st.insert(i); //O(log(n)) 56 | st.insert(n/i); 57 | } 58 | } 59 | } 60 | 61 | /************************************ Primes ******************************************/ 62 | 63 | Problem #3 -> Given an integer 'n' find if it's prime or not? 64 | Primality Check #1: 65 | "Iterate through all the numbers from 2 to n-1 and check the divisibility" 66 | bool isPrime(int n){ //O(n) 67 | for(int i = 2 ; i < n ; ++i){ //from 2 to n-1 68 | if(n%i==0) return 0; //not Prime 69 | } 70 | return 1; //Prime 71 | } 72 | 73 | Observation #1 -> "Square root" 74 | Observation #2 -> "Even Numbers" 75 | 76 | Problem #4 -> Given Q numbers for each of them find if it's prime or not? 77 | Solution #1: 78 | 79 | int A[N]; 80 | void primalityCheck1(){ //O(Q*sqrt(n)) 81 | for(int i = 0 ; i < Q ; ++i){ //The given numbers 82 | bool isPrime = 1; 83 | for(long long j = 2 ; j * j <= A[i] ; ++j){ 84 | if(A[i]%j == 0) isPrime = 0; 85 | } 86 | if(isPrime) printf("%d is a Prime Number\n", A[i]); 87 | else printf("%d is NOT a Prime Number\n", A[i]); 88 | } 89 | } 90 | 91 | Solution #2: "Sieve of Eratosthenes" 92 | 93 | bitset isComposite; 94 | void sieve(){ //O(N*Log(Log(N))) 95 | isComposite[0] = isComposite[1] = 1; 96 | for(long long i = 2 ; i*i <= N ; ++i){ //The Maximum value 97 | if(!isComposite[i]) for(int j = i*i ; j <= N ; j+=i){ 98 | isComposite[j] = 1; 99 | } 100 | } 101 | } 102 | 103 | Goldbech`s conjecture: 104 | -Every even integer greater than 2 can be expressed as the sum of 2 primes. 105 | 106 | /********************************** Factors ************************************/ 107 | 108 | vector > factors; // that represents P^e 109 | void factorize1(){ 110 | for(long long i = 2 ; i*i <= n ; ++i){ 111 | int power = 0; 112 | while(n%i==0){ 113 | n/=i; 114 | ++power; 115 | } 116 | if(power) factors.push_back({i, power}); 117 | } 118 | if(n > 1) factors.push_back({n, 1}); 119 | } 120 | 121 | /********************************** Powring **************************************/ 122 | 123 | -Do you know that A^x = A^(x-1) * A and A^0 = 1 ? 124 | -Do you know that A^x = A^(x/2) * A^(x/2) and A^0 = 1 ? 125 | 126 | int power1(int b, int p){ //O(p) 127 | if(!p) return 1; 128 | return b*power1(b, p-1); 129 | } 130 | 131 | int power2(int b, int p){ //O(Log(p)) 132 | if(!p) return 1; 133 | int ret = power2(b, p/2); 134 | return (p&1 ? ret*ret*b : ret*ret); 135 | } 136 | 137 | /********************************* Modular Arithmetic *******************************/ 138 | 139 | Modular Arithmetic: 140 | (a + b) % m = ((a % m) + (b % m)) % m 141 | (a * b) % m = ((a % m) * (b % m)) % m 142 | (a - b) % m = ((a % m) – (b % m)) % m 143 | (a + m) % m = a%m 144 | (a ^ b) % m = (a ^ ( b % (m-1))) % m 145 | 146 | int add(int a, int b, int m){ 147 | return (a%m + b%m) % m; 148 | } 149 | 150 | int sub(int a, int b, int m){ 151 | return (a%m - b%m) % m; 152 | } 153 | 154 | int mul(int a, int b, int m){ 155 | return (a%m * b%m) % m; 156 | } 157 | 158 | /********************************* GCD & LCM *******************************/ 159 | 160 | int GCD(int a, int b){ //you can use built-in function __gcd(a, b) 161 | if(!b) return a; 162 | return GCD(b, a%b); 163 | } 164 | 165 | int LCM(int a, int b){ 166 | return (a*b)/GCD(a, b); 167 | } 168 | -------------------------------------------------------------------------------- /Number Theory/Number Theory 03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 19 , M = 1e3+5, OO = 0x3f3f3f3f, MOD = 1e9+7; 5 | 6 | typedef long long ll; 7 | 8 | inline ll fixMod(ll a, ll m){ 9 | return (a%m + m)%m; 10 | } 11 | 12 | //a = q*b + r 13 | //q = (a-r)/b 14 | inline ll floor(ll a, ll b){ 15 | return (a - fixMod(a, b))/b; 16 | } 17 | 18 | inline void update(ll& t0, ll& t1, ll q){ 19 | ll t2 = t0 - q*t1; 20 | t0 = t1; 21 | t1 = t2; 22 | } 23 | 24 | //Extended Euclidean Algorithm 25 | //a*x + b*y = g 26 | ll eGCD(ll g0, ll g1, ll& x0, ll& y0){ 27 | ll x1 = y0 = 0, y1 = x0 = 1; 28 | while(g1){ 29 | ll q = g0/g1; 30 | update(g0, g1, q); 31 | update(x0, x1, q); 32 | update(y0, y1, q); 33 | } 34 | return g0; 35 | } 36 | 37 | //Linear Diophantine Equation 38 | //a*x + b*y = c 39 | bool solveLDE(ll a, ll b, ll c, ll& x, ll& y, ll& g){ 40 | g = eGCD(a, b, x, y); 41 | x *= c/g; 42 | y *= c/g; 43 | return !(c%g); 44 | } 45 | 46 | //if gcd(a, m) = 1 -i.e. Coprimes-, returns true 47 | //(a*x)%m = 1 48 | //a*x - m*q = 1 49 | bool modInverse(ll a, ll m, ll& inv){ 50 | ll temp; 51 | ll g = eGCD(a, m, inv, temp); 52 | inv = fixMod(inv, m); 53 | return g == 1; 54 | } 55 | 56 | int main(){ 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Number Theory/Number Theory 04.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | //Euler phi function 8 | //The number of coprimes with n that are < n 9 | ll phi(ll n){ //O(sqrt(n)) 10 | ll res = n; 11 | for(ll i = 2 ; i <= n/i ; i += 1 + (i&1)){ 12 | if(!(n%i)){ 13 | while(!(n%i)) n /= i; 14 | res -= res/i; 15 | } 16 | } 17 | if(n > 1) res -= res/n; 18 | return res; 19 | } 20 | 21 | //Iterative fast power 22 | //b^p = (b^(p/2))^2 23 | ll fPower(ll b, ll p, ll m){ //O(log(p)) 24 | ll res = 1; 25 | while(p){ 26 | if(p&1) res = (res * x)%m; 27 | x = (x * x)%m; 28 | p >>= 1; 29 | } 30 | return res; 31 | } 32 | 33 | //Euler => a^(phi(m)) = a mod m 34 | //Euler => a^(phi(m)-1) = 1 mod m 35 | //Iff a and m are coprimes 36 | inline ll modInversePHI(ll a, ll m){ //O(sqrt(m)) 37 | return fPower(a, phi(m)-1, m); 38 | } 39 | 40 | //Fermat => a^(p-1) = a mod p 41 | //Fermat => a^(p-2) = 1 mod p 42 | //Iff p is prime 43 | inline ll modInversePrime(ll a, ll p){ //O(log(p)) 44 | return fPower(a, p-2, p); 45 | } 46 | 47 | int main(){ 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /Number Theory/PhiSieve.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int N = 1e6+5, OO = 0x3f3f3f3f; 6 | 7 | typedef long long ll; 8 | 9 | ll phi[N]; 10 | void phiSieve(){ 11 | iota(phi, phi+N, 0); 12 | for(ll i = 2 ; i < N ; i += 1 + (i&1)) 13 | if(phi[i] == i) 14 | for(ll j = i ; j < N ; j+=i) 15 | phi[j] -= phi[j]/i; 16 | } 17 | 18 | int main(){ 19 | phiSieve(); 20 | for(int i = 0 ; i < 100 ; ++i){ 21 | printf("%d -> %lld\n", i, phi[i]); 22 | } 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Number Theory/Sieve_Number_of_Divisors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e5 + 5, M = 1e8, OO = 2000000007; 5 | 6 | int numberOfDivisors[N]; 7 | int n; 8 | 9 | void sieve(){ 10 | numberOfDivisors[0] = numberOfDivisors[1] = 1; 11 | for(int i = 2 ; i*i <= n ; ++i){ 12 | if(!numberOfDivisors[i]) for(int j = i ; j < n ; j+=i){ 13 | int e = 0; 14 | int q = j; 15 | while(q%i==0){ 16 | ++e; 17 | q/=i; 18 | } 19 | if(numberOfDivisors[j]) numberOfDivisors[j]*=(e+1); 20 | else numberOfDivisors[j] = e+1; 21 | } 22 | } 23 | } 24 | 25 | int main(){ 26 | // freopen("i.in", "rt", stdin); 27 | // freopen("o.out", "wt", stdout); 28 | n = N; 29 | sieve(); 30 | for(int i = 2 ; i <= 30 ; ++i){ //Note that Primes have exactly 2 divisors 31 | printf("Number %d has %d Divisors\n", i, numberOfDivisors[i]); 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Number Theory/Sieve_Prime_Factors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e5 + 5, M = 1e8, OO = 2000000007; 5 | 6 | int greatestPF[N]; 7 | int n; 8 | 9 | void sieve(){ 10 | greatestPF[0] = greatestPF[1] = 1; 11 | for(int i = 2 ; i*i <= n ; ++i){ 12 | if(!greatestPF[i]) for(int j = i ; j < n ; j+=i){ 13 | greatestPF[j] = i; 14 | } 15 | } 16 | } 17 | 18 | int main(){ 19 | // freopen("i.in", "rt", stdin); 20 | // freopen("o.out", "wt", stdout); 21 | n = N; 22 | int x; 23 | sieve(); 24 | for(int i = 0 ; i < n ; ++i){ 25 | scanf("%d", &x); 26 | printf("Prime Factors of %d are :\n", x); 27 | while(x>1){ 28 | printf("%d ", greatestPF[x]); 29 | x /= greatestPF[x]; 30 | } 31 | puts(""); 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Problem-Solving 2 | 3 | ## Description 4 | 5 | This Repository contains some session notes/codes/solutions to classical problems 6 | 7 | ## Topics included 8 | 9 | - C++ Standard Template Library (STL) notes/usage examples. 10 | 11 | - Some C++ Built-in function notes/usage examples. 12 | 13 | - Time Complexity Analysis session notes/examples. 14 | 15 | - C++ Bitwise operators notes/usage examples in bitmasks. 16 | 17 | - 1D/2D Cumulative (prefix) Sum, Frequency arrays notes/usage examples. 18 | 19 | - Binary Search with 2 (minimization,maximization) Examples. 20 | 21 | - Kadane Algorithm usage example in 1D, 2D and 3D arrays. 22 | 23 | - Union Find (aka Disjoint Sets Union DSU) Data structure with Path Compression. 24 | 25 | - Different Solutions to find/build the LIS (Longest Increasing Subsequence) Problem using: 26 | 27 | - Recursive/Iterative (with Memory Reduction) Dynamic Programming (DP). 28 | 29 | - Binary Search. 30 | 31 | - Segment Tree. 32 | 33 | - Matrix Operations: 34 | 35 | - Addition 36 | 37 | - Multiplication 38 | 39 | - Fast Exponentiation (aka Fast Power). 40 | 41 | TBC.. 42 | -------------------------------------------------------------------------------- /STL(1 of 2).txt: -------------------------------------------------------------------------------- 1 | What to know? 2 | 1- When to use. 3 | 2- Its Features. 4 | 3- Its member Functions. 5 | 4- How to initialize? 6 | 5- How to iterate? 7 | 6- How does it work? 8 | 9 | - What if we want to store a user name and his ID? What if we want to sort an array of them? 10 | - A Cartesian point. 11 | 12 | Pair p; 13 | - pair p = {1, 7}; 14 | - pair p = make_pair(3, -2); 15 | - pair p("Ali", 109); 16 | - pair p = pair(5, 7); 17 | - make_pair(f, s) ... {f, s} 18 | - first, second 19 | 20 | Sequence containers: 21 | 22 | -What if we don't know the size of the array -Not Even the exact maximum- ? 23 | vector v; 24 | Features: 25 | - Opened from the back. 26 | - Dynamic size. 27 | - Constant access time. 28 | - [] operator. 29 | Initialization: 30 | - vector v(size); //initialized by Zeros 31 | - vector v(size, val); 32 | - vector v2(v1); 33 | - vector v2(begin, end); 34 | - vector v = vector(); 35 | Commonly used Member functions: 36 | - begin() 37 | - end() 38 | - rbegin() 39 | - rend() 40 | - resize(size) 41 | - reserve(capacity) ** 42 | - size() 43 | - empty() 44 | - push_back(val) 45 | - pop_back() 46 | - back() 47 | - front() 48 | - insert(it, val) --- insert(it, begin, end) 49 | - erase(it) --- erase(begin, end) 50 | - clear() 51 | Iteration: 52 | for(int i = 0 ; i < n ; ++i){ 53 | scanf("%d", &x); 54 | v.push_back(x); 55 | } 56 | for(int i = 0 ; i < n ; ++i) 57 | printf("%d ", v[i]); 58 | for(int x : v) 59 | printf("%d ", x); 60 | for(auto x = v.begin() ; x!=v.end() ; ++x) 61 | printf("%d ", *x); 62 | 63 | -What if we want to insert in the beginning? 64 | deque dq; 65 | Features: 66 | - Opened from both ends. 67 | - Dynamic size. 68 | - Constant access time. 69 | - [] operator. 70 | Initialization: 71 | - deque dq(size); //initialized by Zeros 72 | - deque dq(size, val); 73 | - deque dq2(dq1); 74 | - deque dq2(begin, end); 75 | - deque dq = deque(); 76 | Commonly used Member functions: 77 | - begin() 78 | - end() 79 | - rbegin() 80 | - rend() 81 | - resize(size) 82 | - size() 83 | - empty() 84 | - push_back(val) 85 | - pop_back() 86 | - back() 87 | - push_front(val) 88 | - pop_front() 89 | - front() 90 | - insert(it, val) --- insert(it, begin, end) 91 | - erase(it) --- erase(begin, end) 92 | - clear() 93 | Iteration: 94 | for(int i = 0 ; i < n ; ++i){ 95 | scanf("%d", &x); 96 | dq.push_back(x); 97 | } 98 | for(int i = 0 ; i < n ; ++i) 99 | printf("%d ", dq[i]); 100 | for(int x : dq) 101 | printf("%d ", x); 102 | for(auto x = dq.begin() ; x!=dq.end() ; ++x) 103 | printf("%d ", *x); 104 | 105 | list l; 106 | Features: 107 | - Constant insertion time. 108 | - Dynamic size. 109 | Initialization: 110 | - list l(size); //initialized by Zeros 111 | - list l(size, val); 112 | - list l2(l1); 113 | - list l2(begin, end); 114 | - list l = list(); 115 | Commonly used Member functions: 116 | - begin() 117 | - end() 118 | - rbegin() 119 | - rend() 120 | - resize(size) 121 | - size() 122 | - empty() 123 | - push_back(val) 124 | - pop_back() 125 | - back() 126 | - push_front(val) 127 | - pop_front() 128 | - front() 129 | - insert(it, val) --- insert(it, begin, end) 130 | - erase(it) --- erase(begin, end) 131 | - clear() 132 | - sort() 133 | - splice(it, list) --- splice(it, list, begin, end) //Cut and paste 134 | - remove(val) 135 | - merge(list) //Merges sorted lists 136 | - unique() 137 | Iteration: 138 | for(int i = 0 ; i < n ; ++i){ 139 | scanf("%d", &x); 140 | l.push_back(x); 141 | } 142 | for(int x : l) 143 | printf("%d ", x); 144 | for(auto x = l.begin() ; x!=l.end() ; ++x) 145 | printf("%d ", *x); 146 | 147 | Container Adapters: 148 | stack st; //LIFO 149 | Features: 150 | - deque with some restrictions. 151 | - Last in first out. 152 | Commonly used Member functions: 153 | - size() 154 | - empty() 155 | - push(val) 156 | - pop() //Avoid RTE 157 | - top() //Avoid RTE 158 | Iteration: 159 | while(!st.empty()){ 160 | printf("%d ", st.top()); 161 | st.pop(); 162 | } 163 | 164 | queue q; //FIFO 165 | Features: 166 | - deque with some restrictions. 167 | - First in first out. 168 | Commonly used Member functions: 169 | - size() 170 | - empty() 171 | - push(val) 172 | - pop() //Avoid RTE 173 | - front() //Avoid RTE 174 | Iteration: 175 | while(!q.empty()){ 176 | printf("%d ", q.front()); 177 | q.pop(); 178 | } 179 | 180 | priority_queue pq; //FIFO 181 | Features: 182 | - Max heap tree. 183 | Commonly used Member functions: 184 | - size() 185 | - empty() 186 | - push(val) 187 | - pop() //Avoid RTE 188 | - top() //Avoid RTE 189 | Iteration: 190 | while(!pq.empty()){ 191 | printf("%d ", pq.top()); 192 | pq.pop(); 193 | } 194 | -------------------------------------------------------------------------------- /STL2.txt: -------------------------------------------------------------------------------- 1 | priority_queue pq; 2 | Features: 3 | - Max heap tree. 4 | - Keeps the maximum value on top of the Tree. 5 | 6 | Commonly used Member functions: 7 | - size() 8 | - empty() 9 | - push(val) //O(log(n)) 10 | - pop() //Avoid RTE 11 | - top() //Avoid RTE 12 | 13 | Iteration: 14 | while(!pq.empty()){ 15 | printf("%d ", pq.top()); 16 | pq.pop(); 17 | } 18 | 19 | -What if we want to get the minimum values? 20 | 1- Multiply values by -1. 21 | 2- Use greater Comparator. 22 | 23 | 24 | set st; 25 | 26 | Features: 27 | - Red Black tree -Balanced Binary Search tree-. 28 | - No Duplicates. 29 | - Seems to be sorted Ascendingly. 30 | - search, insert and erase in O(log(n)) 31 | 32 | Commonly used Member functions: 33 | - begin() 34 | - end() 35 | - rbegin() 36 | - rend() 37 | - insert(val) 38 | - find(val) //iterator 39 | - count(val) // 0|1 40 | - erase(val) || erase(iterator) 41 | - lower_bound(val) //iterator where >= val 42 | - upper_bound(val) //iterator where > val 43 | - size() 44 | - empty() 45 | - clear() 46 | 47 | Iteration: 48 | for(auto x : st){ 49 | printf("%d", x); 50 | } 51 | 52 | for(auto it = st.begin() ; it != st.end() ; ++it){ 53 | printf("%d", *it); 54 | } 55 | 56 | multiset ms; //the same as set but allows Duplicates. 57 | -------------------------------------------------------------------------------- /Segment Tree/RSQ.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 1e5+5 , M = (N<<2), OO = 1000000007; 5 | const double EPS = 0.00001; 6 | 7 | #define lft(x) (x<<1) 8 | #define rit(x) ((x<<1)|1) 9 | #define med(l, r) ((l+r)>>1) 10 | 11 | int n, q, t, a, b; 12 | int A[N]; 13 | 14 | int tr[N<<2]; 15 | 16 | void build(int p, int l, int r){ //O(n*log(n)) 17 | if(l==r) 18 | tr[p] = A[l]; 19 | else{ 20 | build(lft(p), l, med(l, r)); 21 | build(rit(p), med(l, r)+1, r); 22 | tr[p] = tr[lft(p)] + tr[rit(p)]; 23 | } 24 | } 25 | 26 | void update(int p, int l, int r, int idx, int val){ //O(log(n)) 27 | if(l>r || l>idx || rr || l>j || r=i && r<=j) return tr[p]; 40 | else{ 41 | int q1 = sum(lft(p), l, med(l, r), i, j); 42 | int q2 = sum(rit(p), med(l, r)+1, r, i, j); 43 | return q1 + q2; 44 | } 45 | } 46 | 47 | int main(){ 48 | // freopen("i.in", "rt", stdin); 49 | // freopen("o.out", "wt", stdout); 50 | cin.sync_with_stdio(0); 51 | cin >> n; 52 | for(int i = 0 ; i < n ; ++i) 53 | cin >> A[i]; 54 | cin >> q; 55 | build(1, 0, n-1); 56 | while(q--){ 57 | cin >> t >> a >> b; 58 | if(t){ 59 | printf("The sum from %d to %d is %d\n", a, b, sum(1, 0, n-1, a, b)); 60 | }else{ 61 | update(1, 0, n-1, a, b); 62 | } 63 | } 64 | return 0; 65 | } 66 | 67 | /* 68 | Sample Input: 69 | 5 70 | 5 4 3 6 5 71 | 6 72 | 1 0 4 73 | 0 3 -10 74 | 1 0 4 75 | 1 0 0 76 | 0 0 2 77 | 1 0 2 78 | */ 79 | -------------------------------------------------------------------------------- /Strings/KMP.cpp: -------------------------------------------------------------------------------- 1 | //SPOJ EPALIN 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | const int N = 1e5+5, M = 2e5+5, OO = 0x3f3f3f3f; 10 | 11 | int n; 12 | char str[N], pat[M]; 13 | int F[M]; 14 | 15 | int getNextLen(int len, char c){ 16 | while(len && pat[len] != c) 17 | len = F[len-1]; 18 | if(pat[len] == c) ++len; 19 | return len; 20 | } 21 | 22 | void computeF(){ 23 | F[0] = 0; 24 | for(int i = 1 ; i < n ; ++i) 25 | F[i] = getNextLen(F[i-1], pat[i]); 26 | } 27 | 28 | int main(){ 29 | while(~scanf("%s", str)){ 30 | strcpy(pat, str); 31 | reverse(pat, pat+strlen(pat)); 32 | strcat(pat, "#"); 33 | strcat(pat, str); //pat = reversedString + # + givenString 34 | n = strlen(pat); 35 | computeF(); 36 | printf("%s", str); 37 | for(int i = strlen(str)-1-F[n-1] ; ~i ; --i) printf("%c", str[i]); 38 | puts(""); 39 | } 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /Strings/Rabin-Karp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const int N = 19 , M = 1e3+5, OO = 0x3f3f3f3f; 5 | 6 | typedef long long ll; 7 | 8 | inline ll fixMod(ll a, ll m){ 9 | return (a%m + m)%m; 10 | } 11 | 12 | inline void update(ll& t0, ll& t1, ll q){ 13 | ll t2 = t0 - q*t1; 14 | t0 = t1; 15 | t1 = t2; 16 | } 17 | 18 | //Extended Euclidean Algorithm 19 | // a*x + b*y = g 20 | ll eGCD(ll g0, ll g1, ll& x0, ll& y0){ 21 | ll x1 = y0 = 0, y1 = x0 = 1; 22 | while(g1){ 23 | ll q = g0/g1; 24 | update(g0, g1, q); 25 | update(x0, x1, q); 26 | update(y0, y1, q); 27 | } 28 | return g0; 29 | } 30 | 31 | //if gcd(a, m) = 1 -i.e. Coprimes-, returns true 32 | bool modInverse(ll a, ll m, ll& inv){ 33 | ll temp; 34 | ll g = eGCD(a, m, inv, temp); 35 | return g == 1; 36 | } 37 | 38 | //(51*10 + 7) = 517 39 | inline void addLDigit(ll& h, char d, ll base, ll mod){ 40 | h = ((h * base)%mod + d)%mod; 41 | } 42 | 43 | //(517 - 7)/10 = 51 44 | inline void remLDigit(ll& h, char d, ll inv, ll mod){ 45 | h = (fixMod(h-d, mod) * inv)%mod; 46 | } 47 | 48 | //17 + 5*100 = 517 49 | inline void addMDigit(ll& h, ll p, char d, ll mod){ 50 | h = (h + (p*d)%mod)%mod; 51 | } 52 | 53 | //517 - 500 = 17 54 | inline void remMDigit(ll& h, ll p, char d, ll mod){ 55 | h = fixMod(h-(d*p)%mod, mod); 56 | } 57 | 58 | 59 | int main(){ 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /bitwise operations and bitmasks.txt: -------------------------------------------------------------------------------- 1 | 1- How does numbers are saved? 2 | Binary Representation. 3 | 4 | Boolean algebra. 5 | 6 | What's bitwise operations? 7 | 8 | operation operator 9 | and & 10 | or | 11 | Xor ^ 12 | invert ~ 13 | left shift << 14 | right shift >> 15 | 16 | - How to get all the possible permutations of k(e.g k = 3) bits? 17 | 18 | for(int msk = 0 ; msk < (1<