Algorithms for Competitive Programmers
Algorithms for Competitive Programmers
Contents Page
Bipartite graph 1
Floyd 1
DSU 2
Subtree count 2
MST-Kruskal 3
Dijkstra 4
BFS 5
Cycle detection 5
Printing Cycle 6
Tree diameter 6
Bellman 7
Optimized bellman 8
SCC 10
Ordered set 11
Trie 12
Segment tree 13
Bitmask 14
To binary 15
Fast power 15
GCD 16
LCM                              16
● Bipartite graph O(n+m)
 int n;
 vector<vector<int>> adj;
● Floyd O(N3)
 void Floyd(){
   for(int k = 1; k <= n; k++)
       for(int i = 1; i <= n; i++)
           for(int j = 1; j <= n; j++)
               floyd[i][j] = min( floyd[i][k] + floyd[k][j],
 floyd[i][j] );
     return;}
 void process(){
   for(int i = 0; i <= 200; i++) {
       for(int j = 0; j <= 200; j++) {
           if( i == j ) floyd[i][j] = 0;
            else floyd[i][j] = 1000000000;
             // set to size bigger than the biggest cost
       }
   }Return;}
1
● Dijkstra O((n+e) log(e))
void Display(ll node){
      if(node == -1) return;
      Display( parent[node] );
      cout << node << " ";
   }
   int main(){
      for(ll i = 0; i <= 1e6; i++) costs[i] = 1e12;
      //                    cost node
      priority_queue < pair <ll, ll> > pq;
      pq.push( {0, 1} );
      costs[1] = 0;
      parent[1] = -1;
      bool ok = false;
      while(!pq.empty()) {
          ll cost = -pq.top().first;
          ll node = pq.top().second;
          pq.pop();
          if(node == n) {
              ok = true;
              break;
          }
          if (cost > costs[node]) continue;
          for(ll i = 0; i < v[node].size(); i++) {
              if( cost + v[node][i].second < costs[v[node][i].first]) {
                  costs[v[node][i].first] = cost + v[node][i].second;
                  parent[v[node][i].first] = node;
                  pq.push( { -(costs[v[node][i].first]),
   v[node][i].first} );
              }
          }
      }
      if(ok) return Display(n), 0;
      else return cout << -1, 0;
4
● BFS O(n+m)
      vector<vector<int>> adj; // adjacency list representation
      int n; // number of nodes
      int s; // source vertex
      queue<int> q;
      vector<bool> used(n);
      vector<int> d(n), p(n);
      q.push(s);
      used[s] = true;
      p[s] = -1;
      while (!q.empty()) {
          int v = q.front();
          q.pop();
          for (int u : adj[v]) {
              if (!used[u]) {
                  used[u] = true;
                  q.push(u);
                  d[u] = d[v] + 1;
                  p[u] = v;
              }
          }
      }
      bool dfs(int v, int par) { // passing vertex and its parent vertex
          visited[v] = true;
          for (int u : adj[v]) {
              if(u == par) continue; // skipping edge to parent vertex
              if (visited[u]) {
                  cycle_end = v;
                  cycle_start = u;
                  return true;
              }
              parent[u] = v;
              if (dfs(u, parent[u]))
                  return true;
          }
          return false;}
5
● To binary
      void tobinary(int n)
      {
          while(n>0)
          {
              v.push_back(n%2);
              n=n/2;
          }
          for(int i=v.size()-1; i>=0; i--)
              cout << v[i];
          v.clear();
      }
      ll cnt_bit(ll x)
      {
         return __builtin_popcountll(x);
      }
● Fast Power
15
● NCR and NPR
        void calcFacAndInv(ll n)
        {
           fact[0] = inv[0] = 1;
           for (ll i = 1; i <= n; i++)
           {
               fact[i] = (i * fact[i - 1]) % mod;
               inv[i] = fp(fact[i], mod - 2);
           }
        }
        ll ncr(ll n, ll r)
        {
           return ((fact[n] * inv[r]) % mod * inv[n - r]) % mod;
        }
        ll npr(ll n, ll r)
        {
           return (fact[n] * inv[n - r]) % mod;
        }
● Sieve
     bool prime[100000];
        int n = 1000;
        memset(prime , true, sizeof prime );
        prime[0] = prime[1] = false;
        for (int i = 2; i * i <= n; i++)
            if ( prime[i])
                for (int j = i * i; j <= n; j += i)
                    prime[j] = false;
16
● Prime Factorization
void printPrimeFactors(int n) {
      while (n%2 == 0){
         cout<<"2\t";
         n = n/2;
      }
      for (int i = 3; i <= sqrt(n); i = i+2){
         while (n%i == 0){
            cout<<i<<"\t";
            n = n/i;
         }
      }
      if (n > 2)
      cout<<n<<"\t";
   }
17
● Smallest prime factor (optimized) O(log(n))
     bool v[MAX];
     int len, sp[MAX];
     void Sieve(){
        for (int i = 2; i < MAX; i += 2)   sp[i] = 2;//even numbers have
     smallest prime factor 2
        for (lli i = 3; i < MAX; i += 2){
            if (!v[i]){
                sp[i] = i;
                for (lli j = i; (j*i) < MAX; j += 2){
                    if (!v[j*i])   v[j*i] = true, sp[j*i] = i;
                }
            }
        }
     }
     int main() {
        Sieve();
        for (int i = 0; i < 50; i++) cout << sp[i] << endl;
        return;
     }
     void primeFactors(int n)
     {
         while(n%2==0)
         {
             cout << 2 << " ";
             n = n/2;
         }
         // n must be odd at this point. So we can skip, one element (Note
     i = i +2)
         for(int i=3; i<=sqrt(n); i+=2)
         {
             while (n%i==0)
             {
                 cout << i << " ";
                 n/=i;
             }
         }
         // This condition is to handle the case when n, is a prime number
     greater than 2
         if (n>2) cout << n << " "; }
18
● Power & Big power
     ll power(ll b,ll e)
     {
         if(e==0)
             return 1;
         if(e&1)
             return b*power(b*b,e/2);
         return power(b*b,e/2);
     }
     double bigPower(double a, int n)
     {
         double x = a, ret = 1;
         while(n)
         {
             int currentBit = n&1;
             if(currentBit)
                 ret *= x;
             x*=x;
             n = n>>1;
         }
         return ret;
     }
● Is Power of 2
     bool isPowerOfTwo(int x)
     {
         // x will check if x == 0 and !(x & (x - 1)) will check if x is a
     power of 2 or not
         return (x && !(x & (x - 1)));
     }
19
● Perfect Squares
     bool perfectsquares(ll n)
     {
         ll i=4, j=3;
         bool ans=true;
         while(i<=n && ans)
         {
             if(n%i==0)
                 ans=false;
             j+=2;
             i+=j;
         }
         return ans;
     }
● eGCD
20
● Get Divisors
      set<ll>GetDivisors(ll val)
      {
          set<ll> st;
          for(int i=1; i<=sqrt(val); i++)
              if(val%i==0)
                  st.insert(i), st.insert(val/i);
          return st;
      }
      void divisions(ll num)
      {
          vector<ll>v;
          for(ll i=1; i<=sqrt(num); i++ )
          {
              if(num%i==0)
              {
                  v.push_back(i);
                  if(i!=num/i)
                      v.push_back(num/i);
              }
          }
      }
     ● Binary search
 int low = 0, high = n - 1, mid;
     while ( low <= high ) {
         mid = (low + high)/2;
         if ( arr[mid] < k ) low = mid + 1;
         else if ( arr[mid] > k ) high = mid - 1;
         Else return cout << "found", 0;
     }
21
     ● First occurrence
 int low = 0, high = n - 1, mid;
    while ( low <= high ) {
        mid = (low + high)/2;
        if ( arr[mid] < k ) low = mid + 1;
        else if ( arr[mid] > k ) high = mid - 1;
        else {
            ans = mid;
            high = mid - 1;
        }
    }
    cout << ans;
     ● Last occurence
 int low = 0, high = n - 1, mid;
    while ( low <= high ) {
        mid = (low + high)/2;
        if ( arr[mid] < k ) low = mid + 1;
        else if ( arr[mid] > k ) high = mid - 1;
        else {
            ans = mid;
            low = mid + 1;
        }
    }
     ● Lower bound
// get first number less than or equal k
int low = 0, high = n - 1, mid;
    while ( low <= high ) {
        mid = (low + high)/2;
        // if you want the number itself ( arr[mid] <= k )
        if ( arr[mid] < k ) {
            ans = arr[mid];
            low = mid + 1;
        }
        else high = mid - 1;
    }
22
     ● Upper bound
// first number bigger than or equal k
int low = 0, high = n - 1, mid;
    while ( low <= high ) {
        mid = (low + high)/2;
        // if you want the number itself ( arr[mid] >= k )
        if ( arr[mid] < k ) low = mid + 1;
        else if ( arr[mid] > k ) {
            ans = arr[mid];
            high = mid - 1;
        }
        else low = mid + 1;
    }
     ● Ternary
// for int
int low = 0, high = n - 1, mid1, mid2;
    while ( low < high ) {
        mid1 = (low + high)/2;
        mid2 = mid1 + 1;
        if ( mid1 > mid2 ) low = mid2;
        Else high = mid1;
    }
    cout << high;
// for double
int e = (max x), s = (min x), mid1, mid2;
    while ( e - s >= 1e-6 ) {
        mid1 = s + ( e - s )/3;
        mid2 = e - ( e - s )/3;
        if ( arr[mid1] > arr[mid2] ) s = mid1;
        else e = mid2;
    }
     ● Merge sort
void mergesort(vector<int>&arr, int low, int high)
{
    if(low<high)
    {
       int mid=(low+high)/2;
       mergesort(arr, low, mid);
       mergesort(arr, mid+1, high);
    }
}
23
     ● Angles
        const double PI
               = acos(-1.0);
● Solving triangles
        double fixAngle(double A) {
           return A > 1 ? 1 : (A < -1 ? -1 : A);
        }
29
     ● Triangle Areas
30
     ● Points and Lines
        #define X real()
        #define Y imag()
        #define angle(a)        (atan2((a).imag(), (a).real()))
        #define vec(a, b)       ((b)-(a))
        #define same(p1, p2)    (dp(vec(p1,p2),vec(p1,p2)) < EPS)
        #define dp(a, b)    ( (conj(a)*(b)).real() )    // a*b cos(T), if
        zero -> prep
        #define cp(a, b)    ( (conj(a)*(b)).imag() )    // a*b sin(T), if
        zero ->parallel
        #define length(a) (hypot((a).imag(), (a).real()))
        #define normalize(a)     (a)/length(a)
        //#define polar(r,ang) ((r)*exp(point(0,ang))) ==> Already added
        in c++11
        #define rotateO(p, ang) ((p)*exp(point(0,ang)))
        #define rotateA(p, ang, about) (rotateO(vec(about,p),ang)+about)
        #define reflectO(v, m) (conj((v)/(m))*(m))
        point reflect(point p, point p0, point p1) {
            point z = p-p0, w = p1-p0;
            return conj(z/w)*w + p0; // Reflect point p around p0p1
        }
        bool isCollinear(point a, point b, point c) {
              return fabs( cp(b-a, c-a) ) < EPS;
        }
        bool isPointOnRay(point p0, point p1, point p2) {
            if(length(p2-p0) < EPS) return true;
            return same( normalize(p1-p0), normalize(p2-p0) );
        }
        bool isPointOnRay(point a, point b, point c) { // not tested?
            if(!isCollinear(a, b, c))
              return false;
            return dcmp(dp(b-a, c-a), 0) == 1;
        }
        bool isPointOnSegment(point a, point b, point c) {
              return isPointOnRay(a, b, c) && isPointOnRay(b, a, c);
        }
        bool isPointOnSegment(point a, point b, point c) {
              double acb = length(a-b), ac = length(a-c), cb =
        length(b-c);
              return dcmp(acb-(ac+cb), 0) == 0;
        }
31
     double distToLine( point p0, point p1, point p2 ) {
           return fabs(cp(p1-p0, p2-p0)/length(p0-p1)); // area =
     0.5*b*h
     }
     //distance from point p2 to segment p0-p1
32
// Where is P2 relative to segment p0-p1?
// ccw = +1 => angle > 0 or collinear after p1
// cw = -1 => angle < 0 or collinear after p0
// Undefined = 0 => Collinear in range [a, b]. Be careful here
int ccw(point a, point b, point c) {
  point v1(b - a), v2(c - a);
  double t = cp(v1, v2);
     if (t > +EPS)
         return +1;
     if (t < -EPS)
         return -1;
     if (v1.X * v2.X < -EPS || v1.Y * v2.Y < -EPS)
         return -1;
     if (norm(v1) < norm(v2) - EPS)
         return +1;
     return 0;
}
 bool intersect(point p1, point p2, point p3, point p4) {
    // special case handling if a segment is just a point
    bool x = (p1 == p2), y = (p3==p4);
    if(x && y) return p1 == p3;
    if(x)   return ccw(p3, p4, p1) == 0;
    if(y)   return ccw(p1, p2, p3) == 0;
    return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
        ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0; }
// Accurate and efficient
int isInsidePoly(vector<point> p, point p0) {
  int wn = 0; // the winding number counter
  for (int i = 0; i < sz(p); i++) {
      point cur = p[i], nxt = p[(i + 1) % sz(p)];
      if (isPointOnSegment(cur, nxt, p0))
        return true;
      if (cur.Y <= p0.Y) {    // Upward edge
        if (nxt.Y > p0.Y && cp(nxt-cur, p0-cur) > EPS)
            ++wn;
      } else {                // Downward edge
        if (nxt.Y <= p0.Y && cp(nxt-cur, p0-cur) < -EPS)
            --wn;
      }
  }
  return wn != 0;
}
33
     ● Pick’s Theorem
           int n;
           cin >> n;
           pair<int, int> a[n + 5];
           for (int i = 0; i < n; i++)
               cin >> a[i].first >> a[i].second;
           ll area = 0, boundary = 0; // area = x1*y2 - x2*y1
           for (int i = 0; i < n; i++) {
               ll x1 = a[i].first, y1 = a[i].second, x2 = a[(i + 1) %
        n].first, y2 = a[(i + 1) % n].second;
               area += x1 * y2 - x2 * y1;
               boundary += __gcd(abs(x1 - x2), abs(y1 - y2));
           }
           area = abs(area);
           area /= 2;
           cout << area - boundary / 2 + 1 << endl;
//to check if the points are sorted anti-clockwise or clockwise remove the fabs
at the end and it will return -ve value if clockwise
ld polygonArea(ld x[], ld y[], int n) {
       ld ret = 0;
       for(int i = 0; i < n; i++){
              int j = (i + 1) % n;
              ret += x[i] * y[j];
       }
       return fabs(ret) / 2;
}
34
     ● Check if a point is inside a circle
// 0 outside the circle, 1 on the circle line, 2 inside the circle
int inCircle(point cen, ld r, point p) {
    ld sqrlen = lengthSqr(p - cen);
    if (fabs(sqrlen - r * r) < EPS) return 1;
    if (fabs(sqrlen < r * r)) return 2;
    return 0;
}
35
     ● Triangle Area
// angles in radian
ld triangleArea2anglesSide(ld t1, ld t2, ld s) {
        return fabs(s * s * sin(t1) * sin(t2) / (2 *
   sin(t1 + t2)));
}
ld triangleArea2sidesAngle(ld a, ld b, ld t) {
        return fabs(a * b * sin(t) / 2);
}
ld triangleArea3sides(ld a, ld b, ld c) {
        ld s((a + b + c) / 2);
        return sqrt(s * (s - a) * (s - b) * (s - c));
}
     ● Cosine Rule
ld cosRule(ld a, ld b, ld c) {
        ld res = (b * b + c * c - a * a) / (2 * b *
        c); if (res > 1) res = 1;
        if (res < -1) res = -1;
        return acos(res);
}
     ● Sine Rule
ld sinRuleAngle(ld s1, ld s2, ld a1) {
        ld res = s2 * sin(a1) / s1;
        if (res > 1) res = 1;
        if (res < -1) res = -1;
        return asin(res);
}
ld sinRuleSide(ld s1, ld a1, ld a2) {
        // Handle denom = 0
        ld res = s1 * sin(a2) / sin(a1);
        return fabs(res);
}
40
     ● Next greater element O(N)
                   if (!s.empty()) {
                         while (!s.empty() && s.top() <= arr[i]) {
                               s.pop();
                         }
                   }
                   res[i] = s.empty() ? -1 : s.top();
                   s.push(arr[i]);
             }
             for (int i = 0; i < n; i++)
                   cout << arr[i] << " --> " << res[i] << endl;
        }
        int main()
        {
              int arr[] = { 11, 13, 21, 3 };
              int n = sizeof(arr) / sizeof(arr[0]);
             printNGE(arr, n);
             return 0;
        }
● Is it a power of two?
        bool isPowerOfTwo(ll n) {
           /*
           N    = 4,    000100
        N-1 = 3, 000011
        */
           return n && (!(n & (n - 1)));
        }
41
                 max_current = max(arr[i], max_current + arr[i]);
        //fast_Fibonacci O(log(n))
        int fast_Fibonacci(int n){
           int i=1, h=1, j=0, k=0, t;
           while (n > 0) {
               if (n%2 == 1)
                   t = j*h, j = i*h + j*k + t, i = i*k + t;
               t = h*h, h = 2*k*h + t, k = k*k + t, n = n/2;
           }
           return j;
           /* Golden Mean
           double d = sqrt(5);
           double b=pow( (1+d)/2, n);
           double c=pow( (1-d)/2, n);
           cout<<(b-c)/d;
           */
        }
● Pascal
         void Pascal(int n)
         {
            // ncr -> n = row, r = column;
            int arr[n][n];
            for (int line = 0; line < n; line++)
                for (int i = 0; i <= line; i++)
                    if (line == i || i == 0) arr[line][i] = 1;
                    Else arr[line][i] = arr[line - 1][i - 1] + arr[line-1][i] ;
         }
43
         ● Geometry Rules
    45
   -   where s = (a + b + c)/2, a, b, and c are the length of its sides.
 46
                                          𝑛(𝑛 − 3)
     ● Number of diagonals =
                                             2
                 1                1       2      2      2      2
     ● Area =    2
                     𝑃𝑄 𝑠𝑖𝑛(θ)= 4 (𝑏          + 𝑑     − 𝑎   + 𝑐 )𝑡𝑎𝑛(θ)=
        1      2 2        2       2       2     2 2
        4
             4𝑃 𝑄 − (𝑏 + 𝑑 − 𝑎                −𝑐 ) =
                                                                   1
            (𝑠 − 𝑎)(𝑠 − 𝑏)(𝑠 − 𝑐)(𝑠 − 𝑑) − 𝑎𝑏𝑐𝑑𝑐𝑜𝑠                 2
                                                                       (𝐴 + 𝐶)
                              1       2
     ● Area of sector =
                              2
                                  𝑟 θ𝑟𝑎𝑑
47
     ●   Area of triangle =      𝑝(𝑝 − 𝑎)(𝑝 − 𝑏)(𝑝 − 𝑐), where a, b,
                                                        𝑎+𝑏+𝑐
         c are the lengths of the three sides and p =
                                                           2
                                                                =
         𝑎𝑏𝑠𝑖𝑛(𝐶)      |   𝐴𝑥(𝐵𝑦−𝐶𝑦) + 𝐵𝑥(𝐶𝑦−𝐴𝑦)+𝐶𝑥(𝐴𝑦−𝐵𝑦) |          2
                                                           |=
                                                                  3
                  =    |                                              𝑆,
            2                              2                      4
48
     ● c2= a2+b2-2ab cos(C)
              𝑟𝑎𝑑
             θ   *180
     ● θo=
                 Π
49
     ● Math Rules
50
     ●   LCM           = multiply the numbers which has the greatest power from the 2
         numbers even if they're not common
     ●   GCD           = multiply the numbers which has the lowest power from the 2 numbers
         even if they're not common
                                   𝑛
     ●   Arithmetic sequence :
                                   2
                                           (𝑎 + 𝑏)
                                                                          𝑛
                                       𝐿*𝑅−𝑎                              𝑟    −1
     ●   Geometric sequence :
                                        𝑟−1
                                                             = 𝑎 *            𝑟−1
                                       𝑛+𝑛%2 2
     ●   Sum of odd numbers :      (     2
                                            )
                                        𝑛
                                       ( 2 * (2 + 𝑛 − 𝑛 % 2))
     ●   Sum of even numbers:
                                                         2
                                                    2
                                    −𝑏± 𝑏 −4𝑎𝑐
     ●   Quadratic Formula     :
                                        2𝑎
                               𝑛
     ● (1 + 𝑡) = ∑
                      𝑛
                             𝑘=0
                                   ()  𝑛
                                       𝑘
                                                𝑘
                                            𝑡 , 𝑡 == 1 => 2
                                                                              𝑛
                                𝑛                                    𝑛
     ● (𝑥 + 𝑦)
                       𝑛
                           =
                                𝑘=0
                                   ∑       ()
                                            𝑛
                                            𝑘       𝑥
                                                        𝑛−𝑘 𝑘
                                                          𝑦     =   ∑ 𝑥𝑦
                                                                    𝑘=0
                                                                              𝑘 𝑛−𝑘
     ●
                 𝑛!
     ● NPR =
              (𝑛 − 𝑟)!
                 𝑛!
     ● NCR =
             (𝑛 − 𝑟)! * 𝑟!
51
     Sum of the first n odd numbers is .
     PERFECT NUMBERS
     28
496
8128
33550336
8589869056
137438691328
2305843008139952128
2658455991569831744654692615953842176
(n+k-1)C(n) = (n+k-1)C(k-1)
53