


















Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Competitive Programming Cheatsheet
Typology: Study Guides, Projects, Research
Uploaded on 01/21/2025
1 / 26
This page cannot be seen from the preview
Don't miss anything!



















Puzzles
6 Graph Theory 19 6.1 Graph representation.............................................................. 19 6.2 Flood fill algorithm............................................................... 21 6.3 SPFA — shortest path............................................................. 21 6.4 Floyd-Warshall algorithm – shortest path of all pairs............................................ 22 6.5 Prim — minimum spanning tree....................................................... 23 6.6 Eulerian circuit................................................................. 23 6.7 Topological sort................................................................. 24
1 STL Useful Tips
/*** Functions / #include #include
// iostream and cstdio are both using I/O streams // However, they have different behavior, // pay attention on them if you’re using them together.
// cin does not concern with ’\n’ at end of each line // however scanf or getline does concern with ’\n’ at end of each line // ’\n’ will be ignored when you use cin to read char.
// when you use getline(cin, str) to read a whole line of input // please add an extra getline before inputing if previous inputs are numbers cin >> n; getline(cin, str) // wasted getline getline(cin, str) // real input string
(~0u) // infinity (for long and long long) // use (~0u)>>2 for int.
// difference of two sorted ranges void set_difference((first1, last1, first2, last2, result, comp);
// Searching unsigned int find(const string &s2, unsigned int pos1 = 0); unsigned int rfind(const string &s2, unsigned int pos1 = end); unsigned int find_first_of(const string &s2, unsigned int pos1 = 0); unsigned int find_last_of(const string &s2, unsigned int pos1 = end); unsigned int find_first_not_of(const string &s2, unsigned int pos1 = 0); unsigned int find_last_not_of(const string &s2, unsigned int pos1 = end); // Insert, Erase, Replace string& insert(unsigned int pos1, const string &s2); string& insert(unsigned int pos1, unsigned int repetitions, char c); string& erase(unsigned int pos = 0, unsigned int len = npos); string& replace(unsigned int pos1, unsigned int len1, const string &s2); string& replace(unsigned int pos1, unsigned int len1, unsigned int repetitions, char c); // String streams stringstream s1; int i = 22; s1 << "Hello world! " << i; cout << s1.str() << endl;
template
template
template
template
void sort(iterator first, iterator last); void sort(iterator first, iterator last, LessThanFunction comp); void stable_sort(iterator first, iterator last); void stable_sort(iterator first, iterator last, LessThanFunction comp); void partial_sort(iterator first, iterator middle, iterator last); void partial_sort(iterator first, iterator middle, iterator last, LessThanFunction comp); bool is_sorted(iterator first, iterator last); bool is_sorted(iterator first, iterator last, LessThanOrEqualFunction comp); // example for sort, if have array x, start_index, end_index; sort(x+start_index, x+end_index);
/** sort a map */ // You cannot directly sort a map<key type, mapped data type> // if you only want to sort in key type // you can use insert method to copy map into another map // b.insert(make_pair(it->first, it->second) / it is a map iterator */ // this will result a map which sorts key type in increasing order // if you want to sort key type in decreasing order, then declare your map as // something like: // map<char, int, greater
// if you want to sort based on key, you need to copy the data to a vector // where elements of vector are pair. // you can define a PAIR type by using: typedef pair<char, int> PAIR;
// suppose this is the map map<char, int> a;
// sort vector in decreasing order bool cmp_by_value(const PAIR& lhs, const PAIR& rhs) { return lhs.second > rhs.second; }
// sort key in increasing order bool cmp_by_char(const PAIR& lhs, const PAIR& rhs) { return lhs.first < rhs.first; }
// copy map data to vector vector
// sort data sort(b.begin(), b.end(), cmp_by_value);
// you can still call your data by b[i].first and b[i].second. // THE ABOVE CODES ARE EXAMPLE FOR SORTING A MAP. // PLEASE USE IT FOR YOUR OWN DEMANDS.
bool next_permutation(iterator first, iterator last); bool next_permutation(iterator first, iterator last, LessThanOrEqualFunction comp); bool prev_permutation(iterator first, iterator last); bool prev_permutation(iterator first, iterator last, LessThanOrEqualFunction comp);
if (n<=3) return true; if (!(n%2) || !(n%3)) return false; for (int i=5;i*i<=n;i+=6) if (!(n%i) || !(n%(i+2))) return false;
return true; }
// smallest prime factor of a number. function factor(int n) { int a; if (n%2==0) return 2 ; for (a=3;a<=sqrt(n);a++++) { if (n%a==0) return a; } return n; }
// complete factorization int r; while (n>1) { r = factor(n); printf("%d", r); n /= r; }
bool isLeap(int n) { if (n%100==0) if (n%400==0) return true; else return false;
if (n%4==0) return true; else return false; }
int binpow (int a, int n) { int res = 1; while (n) if (n & 1) { res *= a; --n; }
else { a *= a; n >>= 1; } return res; }
long powmod(long base, long exp, long modulus) { base %=^ modulus; long result = 1; while (exp > 0) { if (exp & 1) result = (result * base) % modulus; base = (base * base) % modulus; exp >>= 1; } return result; }
//n! mod p int factmod (int n, int p) { long long res = 1; while (n > 1) { res = (res * powmod (p-1, n/p, p)) % p; for (int i=2; i<=n%p; ++i) res=(res*i) %p; n /= p; } return int (res % p); }
// n>=m, choose M numbers from 1 to N. void combination(int n, int m) { if (n<m) return ; int a[ 50 ]={ 0 }; int k=0;
for (int i=1;i<=m;i++) a[i]=i; while (true) { for (int i=1;i<=m;i++) cout << a[i] << " "; cout << endl;
k=m; while ((k>0) && (n-a[k]==m-k)) k--; if (k==0) break; a[k]++; for (int i=k+1;i<=m;i++)
Cn =
n∑− 1
k=
CkCn− 1 −k =
n + 1
n k
The first terms of this sequence are 2, 5, 14, 42, 132, 429, 1430 when C 0 = 1. This is the number of ways to build a balanced formula from n sets of left and right parentheses. It is also the number of triangulations of a convex polygon, the number of rooted binary tress on n + 1 leaves and the number of paths across a lattice which do not rise above the main diagonal.
n k
= k
n − 1 k
n − 1 k − 1
// This is the number of permutations of length n with exactly k ascending sequences or runs. // Basis: k=0 has value 1 #define MAXN 100 // largest n or k long eularian(n,k) int n,m; { int i,j; long e[MAXN][MAXN]; for (i=0; i<=n; i++) e[i][ 0 ] = 1; for (j=0; j<=n; j++) e[ 0 ][j] = 0; for (i=1; i<=n; i++) for (j=1; j<i; j++) e[i][j] = ke[i-1][j] + (i-j+1)e[i-1][j-1]; return e[n][k]; }
// fast algorithm to find multiplication of two big numbers. import java.math.BigInteger; import java.util.Random;
class Karatsuba { private final static BigInteger ZERO = new BigInteger("0"); public static BigInteger karatsuba(BigInteger x, BigInteger y) { int N = Math.max(x.bitLength(), y.bitLength()); if (N <= 2000) return x.multiply(y); N=(N/2)+(N %2); BigInteger b = x.shiftRight(N); BigInteger a = x.subtract(b.shiftLeft(N)); BigInteger d = y.shiftRight(N); BigInteger c = y.subtract(d.shiftLeft(N)); BigInteger ac = karatsuba(a, c); BigInteger bd = karatsuba(b, d); BigInteger abcd = karatsuba(a.add(b), c.add(d)); return ac.add(abcd.subtract(ac).subtract(bd).shiftLeft(N)).add(bd.shiftLeft(2*N)); }
public static void main(String[] args) { long start, stop, elapsed; Random random = new Random();
int N = Integer.parseInt(args[0]); BigInteger a = new BigInteger(N, random); BigInteger b = new BigInteger(N, random); start = System.currentTimeMillis(); BigInteger c = karatsuba(a, b); stop = System.currentTimeMillis(); System.out.println(stop - start); start = System.currentTimeMillis(); BigInteger d = a.multiply(b); stop = System.currentTimeMillis(); System.out.println(stop - start); System.out.println((c.equals(d))); } }
// the positive integers less than or equal to n that are relatively prime to n. int phi (int n) { int result = n; for (int i=2; i*i<=n; ++i) if(n %i==0) { while(n %i==0) n /= i; result -= result / i; } if (n > 1) result -= result / n; return result; }
n lines can split a plane in (n+1) 2 n+ 1 sub-regions.
3 Searching Algorithms
int find(int l, int r, int k) { int i=0,j=0,x=0,t=0;
if (l==r) return a[l]; x=a[(l+r)/2]; t=a[x]; a[x]=a[r]; a[r]=t; i=l-1;
for (int j=l; j<=r-1;j++) if (a[j]<=a[r]) { i++; t=a[i]; a[i]=a[j]; a[j]=t; } i++;
"little needs to be done in leaving it. The only minor complication is that the "+ "logic which is correct late in the string erroneously gives non-proper "+ "substrings at the beginning. This necessitates some initialization code.";
string b = "table";
int p = KMP(a, b); cout << p << ": " << a.substr(p, b.length()) << " " << b << endl;
return 0 ; }
4 Dynamic Programming
#include
using namespace std;
int f[ 1000 ]={ 0 }; int n=0, m=0;
int main(void) { cin >> n >> m;
for (int i=1;i<=n;i++) { int price=0, value=0; cin >> price >> value;
for (int j=m;j>=price;j--) if (f[j-price]+value>f[j]) f[j]=f[j-price]+value; }
cout << f[m] << endl;
return 0 ; }
#include
using namespace std;
int f[ 1000 ]={ 0 }; int n=0, m=0;
int main(void) { cin >> n >> m;
for (int i=1;i<=n;i++) {
int price=0, value=0; cin >> price >> value;
for (int j=price; j<=m; j++) if (f[j-price]+value>f[j]) f[j]=f[j-price]+value; }
cout << f[m] << endl;
return 0 ; }
int dp[ 1001 ][ 1001 ];
int lcs(const string &s, const string &t) { int m = s.size(), n = t.size(); if (m == 0 || n == 0) return 0 ; for (int i=0; i<=m; ++i) dp[i][ 0 ] = 0; for (int j=1; j<=n; ++j) dp[ 0 ][j] = 0; for (int i=0; i<m; ++i) for (int j=0; j<n; ++j) if (s[i] == t[j]) dp[i+1][j+1] = dp[i][j]+1; else dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1]); return dp[m][n]; }
#include
using namespace std;
int a[ 100 ]={ 0 }; int b[ 100 ]={ 0 }; int f[ 100 ]={ 0 }; int n=0, m=0;
int main(void) { cin >> n; for (int i=1;i<=n;i++) cin >> a[i]; cin >> m; for (int i=1;i<=m;i++) cin >> b[i];
for (int i=1;i<=n;i++) { int k=0; for (int j=1;j<=m;j++) {
// URAL 1146 Maximum Sum #include
using namespace std;
int a[ 150 ][ 150 ]={ 0 }; int c[ 200 ]={ 0 };
int maxarray(int n) { int b=0, sum=-100000000; for (int i=1;i<=n;i++) { if (b>0) b+=c[i]; else b=c[i]; if (b>sum) sum=b; }
return sum; }
int maxmatrix(int n) { int sum=-100000000, max=0;
for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) c[j]=0;
for (int j=i;j<=n;j++) { for (int k=1;k<=n;k++) c[k]+=a[j][k]; max=maxarray(n); if (max>sum) sum=max; } }
return sum; }
int main(void) { int n=0; cin >> n; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) cin >> a[i][j];
cout << maxmatrix(n); return 0 ; }
#define MAXN 100 // largest n or m long int_coefficient(n,k) // compute f(n,k)
int n,m; { int i,j; long f[[MAXN][MAXN]; f [ 1 ][ 1 ] = 1; for (i=0;i<=n;i++) f[i][ 0 ] = 0; for (i=1; i<=n; i++) for (j=1; j<i; j++) if (i-j <= 0) f[i][j] = f[i][k-1]; else f[i][j] = f[i-j][k]+f[i][k-1]; return f[n][k]; }
Number of ways to partition n + 1 items into k sets.
{ n k
= k
n − 1 k
n − 1 k − 1
where (^) { n 1
n n
5 Trees
int L[ 100 ]={ 0 }; int R[ 100 ]={ 0 };
void DLR(int m) { cout << m << " "; if (L[m]!=0) DLR(L[m]); if (R[m]!=0) DLR(R[m]); }
void LDR(int m) { if (L[m]!=0) LDR(L[m]); cout << m << " "; if (R[m]!=0) LDR(R[m]); }
void LRD(int m) { if (L[m]!=0) LRD(L[m]); if (R[m]!=0) LRD(R[m]); cout << m << " "; }
int main(void) { cin >> n; for (int i=1;i<=n;i++) cin >> L[i] >> R[i];
int main(void) { cin >> n;
for (int i=1;i<=n;i++) cin >> l[i] >> r[i];
d=depth( 1 ); mystack.push( 1 ); width( 1 );
cout << w << " " << d << endl;
return 0 ; }
6 Graph Theory
// The most common way to define graph is to use adjacency matrix // example: // (1) (2) (3) (4) (5) // (1) 2 0 5 0 0 // (2) 4 2 0 0 1 // (3) 3 0 0 1 4 // (4) 6 9 0 0 0 // (5) 1 1 1 1 5 // it’s always a square matrix. // suppose a graph has n nodes, if given exactly adjacency matrix for (int i=1;i<=n;i++) for (int j=1;i<=n;j++) { cin << a[i][j] << endl; } // Usually will go like this representation in data // start_node end_node weight // suppose m lines for (int i=1;i<=m;i++) { int x=0, y=0, t=0; cin >> x >> y >> t; a[x][y]=t; // if undirected graph a[y][x]=t; } // another variant: on the ith line, has data as // end_node weight // when you read data, you can assign matrix as a[i][x]=t; // if undirected graph a[x][i]=t;
// Initialization of graph !!!IMPORTANT // Depends on usage, normally initialize as 0 for all elements in matrix. // so that 0 means no connection, non-0 means connection // (for problem without weight, use weight as 1) // If weights are important in this context (especially searching for path)
// Initialize graph as infinity for all elements in matrix.
// Another way to store graph is Adjacency list // No space advantage if using array (unknown maximum number for in-degree). // Big space advantage if using dynamic data structure (like list, vector). // each row represent a node and its connectivity. // we don’t need it so much due to it’s search efficiency. // let’s define a node as struct Node{ int id; // node id int w; // weight }; // suppose n nodes and m lines of inputs as // start_node end_node weight // assume using
/**** Special Structure ****/
// Special structure here is usually not a typical graph, like city-blocks, triangles // They are represented in 2-d array and shows weights on nodes instead of edges. // Note that in this case travel through edge has no cost, but visit node has cost.
// Triangles: Read data like this // 1 // 1 2 // 4 2 7 // 7 3 1 5 // 6 2 9 4 6 for (int i=1;i<=n;i++) for (int j=i;j<=n;j++) cin >> a[i][j];
// Simple city-blocks: it’s just like first form of adjacency matrix, but this time // represents weights on nodes, may not be square matrix. // 1 2 4 5 6 // 2 4 5 1 3 // 4 5 2 3 6 for (int i=1;i<=n;i++) for (int j=1;<=m;j++) cin >> a[i][j];
// More complex data structures: typical city-block structure may has some constraints on // questions, but it has no boundaries. However, some questions requires to form a maze. // In these cases, data structures can be very flexible, it totally depends on how the question // presents the data. A usual way is to record it’s adjacent blocks information: struct Block{ bool l[ 4 ]; // if has 8 neighbors then use bool l[8];