You are on page 1of 25

Turing Machine, IIIT Hyderabad

Team Reference Material


December 9th, 2011.

Template
/* Author : Turing Machine */
#include <iostream>
#include <cstdio>
#include <vector>
#include <cassert>
#include <sstream>
#include <map>
#include <set>
#include <climits>
#include <stack>
#include <queue>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdlib>
using namespace std;
#define
#define
#define
#define
#define
#define
#define
#define

.vimrc
=========================================
set shiftwidth=3
set makeprg=g++\ %\ -Wall
map <F3> :w <CR> :make<CR> <CR>
map <F2> :cn<CR>
imap <tab> <c-n>
set cindent
autocmd BufNewFile *.cpp r ~/start.cpp
set wrapscan
=========================================

FOR(i,a,b) for(int i= (int )a ; i < (int )b ; ++i)


REP(i,n) FOR(i,0,n)
PB push_back
INF 1000000000
ALL(x) x.begin(),x.end()
LET(x,a)
__typeof(a) x(a)
IFOR(i,a,b) for(LET(i,a);i!=(b);++i)
EACH(it,v)
IFOR(it,v.begin(),v.end())

typedef pair<int,int>
typedef vector<int>
typedef long long

PI;
VI;
LL;

DOs and DONTs 1.


2.
3.
4.
5.

Check the Array Sizes [Each and Everyone of them.]


Overflows - Check for overflow in the code.
Take input till EOF always.
Truncate/round decimals.
If a wrong answer comes, then FIND a case where it goes wrong.

Graph Theory
Topological Sort
//tOrd = topologicalOrder
//tSort = topologicalSort
#define MAXN 200000
int n,visited[MAXN];
vector<PI> graph[MAXN];
VI tOrd;
void dfs(int i){
if(visited[i]) return;
visited[i] = true;
EACH(it,graph[i]) dfs(it->first);
tOrd.PB(i);
}
void tSort(){
tOrd.clear();memset(visited,0,sizeof(visited));
REP(i,n) dfs(i);
}

Strongly Connected Components


vector<PI> reverseGraph[MAXN];
void getComponent(int i, vector<int> &comp,int label){
if(visited[i]) return;
visited[i]=label;comp.push_back(i);
EACH(it,reverseGraph[i]) getComponent(it->first,comp,label);
}
void SCC(VII &components){
REP(i,n) reverseGraph[i].clear();
REP(i,n) EACH(it,graph[i]) reverseGraph[it->first].PB(PI(i,it->second));
tSort();components.clear();memset(visited,0,sizeof(visited));
reverse(tOrd.begin(),tOrd.end());
int currentLabel = 1;
EACH(it,tOrd) if(!visited[*it]){
VI temp;getComponent(*it,temp,currentLabel);currentLabel++;
components.PB(temp);
}
}

Bellman-Ford
int n,dist[MAXN];
int bellmanFord(int source,int destination) {
fill(dist, dist + n, INF); dist[source] = 0;
REP (i,n+1) {
bool state = false;
REP (j,n) EACH (it,graph[j]) if (dist[it->first] > dist[j] + it->second) {
dist[it->first] = (dist[j] + it->second);
state = true;
}

3
}
}
if(state) return -INF; // Negative Weight Cycle.
return dist[destination];
}

Bi-Connected Components
VI graph[100003],G2[100003];/* G2[i] will store all the vertices in component i */
int visited[100003],from[100003],upTime[100003],discoveryTime[100003],label[100003], dfsTime,n;
void dfs(int v){
int parentEdges=0;visited[v] = 1;
upTime[v] = discoveryTime[v] = ++dfsTime;
EACH(it,graph[v]){
if(!visited[*it]){
from[*it] = v;dfs(*it);upTime[v] <?= upTime[*it];
}
else {
if(*it != from[v]){
upTime[v] <?= discoveryTime[*it];
}
else {
if(parentEdges) upTime[v] <?= discoveryTime[*it];
parentEdges++;
}
}
}
}
bool isBridge(int i,int j){
if(from[i] != j && from[j] != i) return false;
int low = ((from[i] == j)?i:j);
return (upTime[low] == discoveryTime[low]);
}
void FindBridges(int root){
from[root] = root;dfsTime = 0;
fill(visited,visited+n,0);dfs(root);
}
void ContractCercuits(int root){
fill(label,label+n,0);label[root] = 1;int color = 1;
queue<int> q;q.push(root);
while(!q.empty()){
int cur = q.front();q.pop();
EACH(it,graph[cur]) if(!label[*it]){
if(isBridge(cur,*it)){
label[*it] = ++color;
}
else {
label[*it] = label[cur];
}
q.push(*it);
}
}
REP(i,color) G2[i].clear();

4
REP(i,n) if(label[i]) G2[label[i]-1].PB(i);
}

Dijkstra Algorithm
int n,dist[MAXN];
int dijkstra(int source, int destination) {
fill(dist, dist + n, INF); dist[source] = 0;
set<PI> s; s.insert(PI(0, source));
while (!s.empty()) {
PI top = *s.begin(); s.erase(s.begin());
if (top.second == destination) {
return dist[destination];
}
EACH (it,graph[top.second]) {
if (dist[it->first] > dist[top.second] + it->second) {
if (dist[it->first] != INF) {
s.erase(s.find(PI(dist[it->first], it->first)));
}
dist[it->first] = dist[top.second] + it->second;
s.insert(PI(dist[it->first], it->first));
}
}
}
return INF;
}

Maximum Flow - Dinics.


class FlowDinics {
private:
struct edge {
int to, back, cap;
edge() {to = back = cap = -1;}
edge(int _to, int _cap, int _back) : to(_to), cap(_cap), back(_back) {}
};
vector<vector<edge> > graph;
VI Layers,now;
int n, source, sink;
public:
FlowDinics(int _n,int _source,int _sink) : n(_n), source(_source), sink(_sink) {
graph.resize(n);Layers.resize(n);now.resize(n);
REP(i,n) graph[i].clear();
}
~FlowDinics() {
REP(i,n) graph[i].clear();
}
void insert(int i,int j,int cap) {
graph[i].PB(edge(j,cap,graph[j].size()));
graph[j].PB(edge(i,0,graph[i].size()-1));
}

5
int bfs() {
fill(ALL(Layers),-1);
Layers[sink] = 0;
queue<int> Q; Q.push(sink);
int top, from, to, cap, index;
while(!Q.empty()) {
top = Q.front(); Q.pop();
REP(i,graph[top].size()) {
from = graph[top][i].to; index = graph[top][i].back;
if(graph[from][index].cap && Layers[from] == -1) {
Layers[from] = Layers[top] + 1;
Q.push(from);
}
}
}
return (Layers[source] != -1);
}
int dfs(int node,int val) {
if(node == sink) {
return val;
}
int flow, to, cap;
for(int& start = now[node] ; start < graph[node].size(); ++start) {
to = graph[node][start].to;
cap = graph[node][start].cap;
if(cap > 0 && Layers[node] == Layers[to] + 1) {
flow = dfs(to,min(val,cap));
if(flow) {
graph[node][start].cap -= flow;
graph[to][graph[node][start].back].cap += flow; return flow;
}
}
}
return 0;
}
int flow() {
int ret = 0, flow = 0;
while(bfs()) {
fill(ALL(now),0);
while(flow = dfs(source,INF)) ret += flow;
}
return ret;
}
};

Bipartite Matching
#define Max 60000
VI graph[Max];
int visited[Max], match[Max], pos[Max], track;
int dfs(int i) {

6
int size, j;
if(visited[i] == track) return 0;
visited[i] = track;
size = graph[i].size();
REP(loop,size) {
if(++pos[i] == size) pos[i] = 0;
j = graph[i][pos[i]];
if(match[j] < 0 || dfs(match[j])) {
match[j] = i;
return 1;
}
}
return 0;
}
int matching() {
memset(visited,0,sizeof visited);
memset(pos,0,sizeof pos);
memset(match,-1,sizeof match);
int ret = 0;
REP(i,n) {
if(graph[i].size()) {
++track; ret += dfs(i);
}
}
return ret;
}

Assignment Problem - KuhnMunkras Algorithm. Optimal Assignment.


/***
* fill the matrix C, with C[i][j] defining cost of matching i to j
* optmatch(nx,ny);
* int Ans = 0;
* for (int i = 0; i < ind; i ++) if (X[i] >= 0) Ans += C[i][X[i]];
* output Ans
***/
#define MaxN 2000
int C[MaxN][MaxN],X[MaxN],Y[MaxN],n;
void optmatch(int nx, int ny){
int Lx[MaxN], Ly[MaxN], Q[MaxN], prev[MaxN];
int i, j, k, s, head, tail;
for (i = 0; i < nx; i++){
Lx[i] = Ly[i] = 0;
for (j = 0; j < ny; j++)
Lx[i] >?= C[i][j];
}
memset(X, -1, sizeof(X));
memset(Y, -1, sizeof(Y));
i = 0;
while (i < nx){
memset(prev, -1, sizeof(prev));
for (Q[0] = i, head = 0, tail = 1; head < tail && X[i] < 0; head++) {
s = Q[head];

7
for (j = 0; j < ny && X[i] < 0; j++) {
if (Lx[s] + Ly[j] > C[s][j] || prev[j] >= 0) continue;
Q[tail++] = Y[j];
prev[j] = s;
if (Y[j] < 0) while (j >= 0) {s = prev[j]; Y[j] = s; k = X[s]; X[s] = j; j = k;}
}
}
if (X[i] >= 0) i ++;
else {
k = (1 << 30);
for (head = 0; head < tail; head++) {
s = Q[head];
for (j = 0; j < ny; j++)
if (prev[j] == -1) k <?= (Lx[s] + Ly[j] - C[s][j]);
}
for (j = 0; j < tail; j++) Lx[Q[j]] -= k;
for (j = 0; j < ny; j++) if (prev[j] >= 0) Ly[j] += k;
}
}
}

MinCostMaxFlow - Bellman Ford, Works for Negative Cost Edges also.


#define MAXN 175
int cap[MAXN][MAXN], flow[MAXN][MAXN], cost[MAXN][MAXN], dist[MAXN], prev[MAXN];
int n, sink, source, total_cost;
bool reach[MAXN];
inline int cf(int i, int j) {
return cap[i][j];
}
inline int costf(int i, int j) {
return cost[i][j];
}
inline void pushf(int i, int j, int x) {
total_cost += costf(i, j) * x;
cap[i][j] -= x; cap[j][i] += x;
}
int augment(void) {
bool changed;
memset(reach,0,sizeof reach);
reach[source] = changed = true;
dist[source] = 0;
while (changed) {
changed = false;
REP(i,n) if (reach[i]) REP(j,n) if (cf(i, j))
if (!reach[j] || dist[i] + costf(i, j) < dist[j]) {
reach[j] = changed = true;
dist[j] = dist[i] + costf(i, j);
prev[j] = i;
}
}
if (!reach[sink]) return 0;
int ret = INF;

8
for (int i = sink; i != source; i = prev[i]) ret = min(ret, cap[prev[i]][i]); //pushf(prev[i],
for (int i = sink; i != source; i = prev[i]) pushf(prev[i], i, ret);
return ret;
}
int mcmf(void) {
int ret, x;
ret = total_cost = 0;
while (x = augment()) ret += x;
return ret;
}

Min-cost max-flow Dijkstra


struct MCMF {
typedef int ctype;
enum { MAXN = 1000, INF = INT_MAX };
struct Edge { int x, y; ctype cap, cost; };
vector<Edge> E;
vector<int> adj[MAXN];
int N, prev[MAXN];
ctype dist[MAXN], phi[MAXN];
MCMF(int NN) : N(NN) {}
void add(int x, int y, ctype cap, ctype cost) { // cost >= 0
Edge e1={x,y,cap,cost}, e2={y,x,0,-cost};
adj[e1.x].push_back(E.size()); E.push_back(e1);
adj[e2.x].push_back(E.size()); E.push_back(e2);
}
void mcmf(int s, int t, ctype &flowVal, ctype &flowCost) {
int x;
flowVal = flowCost = 0; memset(phi, 0, sizeof(phi));
while (true) {
for (x = 0; x < N; x++) prev[x] = -1;
for (x = 0; x < N; x++) dist[x] = INF;
dist[s] = prev[s] = 0;
set< pair<ctype, int> > Q;
Q.insert(make_pair(dist[s], s));
while (!Q.empty()) {
x = Q.begin()->second; Q.erase(Q.begin());
FOREACH(it, adj[x]) {
const Edge &e = E[*it];
if (e.cap <= 0) continue;
ctype cc = e.cost + phi[x] - phi[e.y];
if (dist[x] + cc < dist[e.y]) {
Q.erase(make_pair(dist[e.y], e.y));
dist[e.y] = dist[x] + cc;
prev[e.y] = *it;
Q.insert(make_pair(dist[e.y], e.y));
}
}
}
if (prev[t] == -1) break;

// ***

9
ctype z = INF;
for (x = t; x != s; x = E[prev[x]].x) z = min(z, E[prev[x]].cap);
for (x = t; x != s; x = E[prev[x]].x)
{ E[prev[x]].cap -= z; E[prev[x]^1].cap += z; }
flowVal += z;
flowCost += z * (dist[t] - phi[s] + phi[t]);
for (x = 0; x < N; x++) if (prev[x] != -1) phi[x] += dist[x];
// ***
}
}
};

MinCostMaxFlow - CycleCancellingAlgorithm
1. Repeatedly find negative cost cycles in the graph, using Bellman Ford.
2. Circulate flow across these cycles. Update Graph.
3. Algorithm ends when no cycle is found.

Minimum Cut - Stoer Wagner


/**
* Returns the minimum set of edges that, when removed, disconnect the graph.
* Complexity: O(n^3).
* graph contains the adjacency matrix. graph[i][j] is 0 if there is no edge between i and j.
* Returns 0 is the graph is disconnected.
**/
#define MAXN 501
#define MAXW 10000000000LL
int graph[MAXN][MAXN], v[MAXN], na[MAXN];
LL w[MAXN];
bool a[MAXN];
LL minCut(int n) {
if(!isConnected(n)) {
return 0;
}
REP (i,n) v[i] = i;
LL best = MAXW * n * n;
while (n > 1) {
a[v[0]] = true;
FOR (i,1,n) {
a[v[i]] = false;
na[i - 1] = i;
w[i] = graph[v[0]][v[i]];
}
int prev = v[0];
FOR (i,1,n) {
int zj = -1;
FOR (j,1,n) if (!a[v[j]] && (zj < 0 || w[j] > w[zj])) {
zj = j;
}
a[v[zj]] = true;
if (i == n - 1) {

10
best = min(best, w[zj]);
REP (j,n) {
graph[v[j]][prev] = graph[prev][v[j]] += graph[v[zj]][v[j]];
}
v[zj] = v[--n];
break;
}
prev = v[zj];
FOR (j,1,n) if (!a[v[j]]) {
w[j] += graph[v[zj]][v[j]];
}
}
}
return best;
}

Matrix-tree theorem. Let matrix = [ ], where is the number of multiedges between and
, for = , and = deg . Number of spanning trees of a graph is equal to the determinant of a
matrix obtained by deleting any -th row and -th column from . If is a multigraph and is an
edge of , then the number () of spanning trees of satisfies recurrence () = ()+ (/),
when is the multigraph obtained by deleting , and / is the contraction of by (multiple
edges arising from the contraction are preserved.)
Euler tours. Euler tour in an undirected graph exists iff the graph is connected and each vertex has
an even degree. Euler tour in a directed graph exists iff in-degree of each vertex equals its out-degree,
and underlying undirected graph is connected. Construction:
doit(u):
for each edge e = (u, v) in E, do: erase e, doit(v)
prepend u to the list of vertices in the tour
Stable marriages problem. While there is a free man : let be the most-preferred woman to
whom he has not yet proposed, and propose to . If is free, or is engaged to someone whom
she prefers less than , match with , else deny proposal.
Tarjans offline LCA algorithm. (Based on DFS and union-find structure.)
DFS(x):
ancestor[Find(x)] = x
for all children y of x:
DFS(y); Union(x, y); ancestor[Find(x)] = x
seen[x] = true
for all queries {x, y}:
if seen[y] then output "LCA(x, y) is ancestor[Find(y)]"
2-SAT. Build an implication graph with 2 vertices for each variable for the variable and its inverse;
for each clause add edges (, ) and (, ). The formula is satisfiable iff and are in distinct
SCCs, for all . To find a satisfiable assignment, consider the graphs SCCs in topological order from
sinks to sources (i.e. Kosarajus last step), assigning true to all variables of the current SCC (if it
hasnt been previously assigned false), and false to all inverses.

11

Combinatorics
Sums

= ( + 1)/2
=0

2 = ( + 1)(2 + 1)/6
=0

4
5
4
3
=0 = (6+1+ 15 + 10 )/30
1)/( 1)
=0 = (
2
1 + + + = 1/(1 )

= ( + )( + 1)/2
=

3 = 2 ( + 1)2 /4
=0

5
6
5
4
2
=0 = (2 + 6 + 5+1 )/12
+ +2 )/( 1)2
=0 = ( ( + 1)

Binomial coefficients
() (1) (1)
= + 1

Number
Number
Number
Number

of
of
of
of

(+1)
ways to pick a multiset of size from elements:
(
)
( )
-tuples of non-negative integers with sum : +1
, at most : +
1

( 1 )
-tuples of positive integers with sum : 1
( )
lattice paths from (0, 0) to (, ), restricted to east and north steps: +

Harmonic Progression.

2
4
=1 1/ = () + 0.577215664901532 + 1/(2) 1/(12 ) + 1/(120 ) . . .
()

modulo p.

()

( )
mod equals the product of mod where
1 2 . (. . )and 1 2 . . . are the
(1) digits
(4) of and when written in base .
(e.g - 21
mod
17
equals
*
mod 17.)
3
0
3

Derangements. Number of permutations of = 0, 1, 2, . . . elements without fixed points is

1, 0, 1, 2, 9, 44, 265, 1854, 14833, . . . Recurrence: = ( 1)((1


) + 2 ) = 1 + (1) .

Corollary: number of permutations with exactly fixed points is .


Stirling numbers of 1 kind. , is (1) times the number of permutations
of elements

with exactly permutation cycles. |, | = |1,1 | + ( 1)|1, |.


=0 , =
Stirling numbers of 2 kind. , is the number of ways to partition a set
elements into
of

exactly non-empty subsets. , = 1,1 + 1, . ,1 = , = 1. = =0 ,


Bell numbers.
number of partitions of elements. 0 , . . . = 1, 1, 2, 5, 15, 52, 203, . . .
( ) is the
+1 = =0 = =1 , . Bell triangle: = ,1 = 1,1 , , = 1,1 + ,1 .

Number Theory
Linear diophantine equation. + = . Let = gcd(, ). A solution exists iff |. If (0 , 0 )
is any solution, then all solutions are given by (, ) = (0 + , 0 ), Z. To find some solution
(0 , 0 ), use extended GCD to solve 0 + 0 = = gcd(, ), and multiply its solutions by .
Linear diophantine equation in variables: 1 1 + + = has solutions iff gcd(1 , . . . , )|.
To find some solution, let = gcd(2 , . . . , ), solve 1 1 + = , and iterate with 2 2 + = .
Multiplicative inverse of modulo : in + = 1, or ()1 (mod ).
Chinese Remainder Theorem. System (mod ) for = 1, . . . , , with pairwise relatively-

12

prime has a unique solution modulo = 1 2 . . . : =

where is modular inverse of


modulo .

1 1
1

+ +

(mod ),

System (mod ), (mod ) has solutions iff (mod ), where = gcd(, ). The
, and equals: + ( )/ + ( )/ (mod ),
solution is unique modulo =

where and are integer solutions of + = gcd(, ).


Prime-counting function. () = |{ 6 : is prime}|. / ln() < () < 1.3/ ln().
(1000) = 168, (106 ) = 78498, (109 ) = 50 847 534. -th prime ln .

Fermat primes. A Fermat prime is a prime of form 22 + 1. The only known Fermat primes are 3,
5, 17, 257, 65537. A number of form 2 + 1 is prime only if it is a Fermat prime.
Perfect numbers. > 1 is called perfect if it equals sum of its proper divisors and 1. Even is
perfect iff = 21 (2 1) and 2 1 is prime (Mersennes). No odd perfect numbers are yet found.
Carmichael numbers. A positive composite is a Carmichael number (1 1 (mod ) for all
: gcd(, ) = 1), iff is square-free, and for all prime divisors of , 1 divides 1.
+1

Number/sum of divisors.

(11

. . . )

=1 (

+ 1).

(11

. . . )

1
=1 1 .

Eulers phi function. () = |{ N, 6 , gcd(, ) = 1}|.

gcd(,)

() = ()()
. ( ) = 1 ( 1).
| ( ) = .
| () =
(gcd(,))
Eulers theorem. () 1 (mod ), if gcd(, ) = 1.
Wilsons theorem. is prime iff ( 1)! 1 (mod ).
Mobius function. (1) = 1. () = 0, if is not squarefree. () = (1) , if is the
product of
distinct primes. Let , be functions on positive integers. If for all , () = | (), then

() = | () ( ), and vice versa. () = | () .


| () = 1.

If is multiplicative, then | () () = | (1 ()), | ()2 () = | (1 + ()).


Primitive roots. If the order of modulo (min > 0: 1 (mod )) is (), then is
called a primitive root. If has a primitive root, then it has (()) distinct primitive roots.
has a primitive root iff is one of 2, 4, , 2 , where is an odd prime. If has a primitive root
, then for all coprime to , there exists unique integer = ind () modulo (), such that
(mod ). ind () has logarithm-like properties: ind(1) = 0, ind() = ind() + ind().
If is prime and is not divisible by , then congruence (mod ) has gcd(, 1) solutions
if (1)/ gcd(,1) 1 (mod ), and no solutions otherwise. (Proof sketch: let be a primitive root,
and (mod ), (mod ). (mod ) iff (mod ) iff (mod ).)
Pythagorean triples. Integer solutions of 2 + 2 = 2 All relatively prime triples are given by:
= 2, = 2 2 , = 2 + 2 where > , gcd(, ) = 1 and (mod 2). All other
triples are multiples of these. Equation 2 + 2 = 2 2 is equivalent to ( +
)2 + (
)2 = 2 .
2
2
Postage stamps/McNuggets problem. Let , be relatively-prime integers. There are exactly
1
(1)(1) numbers not of form + (, > 0), and the largest is (1)(1)1 = .
2
Fermats two-squares theorem. Odd prime can be represented as a sum of two squares iff
1 (mod 4). A product of two sums of two squares is a sum of two squares. Thus, is a sum of
two squares iff every prime of form = 4 + 3 occurs an even number of times in s factorization.

13

Utilities - Number Theory.


LL calculateModulo(LL a, LL b, LL n) {
LL res = 0;
while (b) {
if (b & 1) {
--b; res = (res + a) % n;
}
else{
b >>= 1;a <<= 1;
a %= n;
}
}
return res;
}
inline LL moduloSpecial(LL b, LL p, LL n) {
LL x = 1, y = b;
while (p) {
if (p&1) x = calculateModulo(x, y, n);
y = calculateModulo(y, y, n);
p >>= 1;
}
return x % n;
}
bool miller(LL n, LL iteration) {
if (n < 2) return false;
if (n != 2 && n % 2 == 0) return false;
LL d = n-1;
while (d % 2 == 0) d >>= 1;
REP(i, iteration) {
LL a = rand() % (n - 1) + 1, temp = d;
LL mod = moduloSpecial(a, temp, n);
while (temp != n - 1 && mod != 1 && mod != n - 1) {
mod = calculateModulo(mod, mod, n);
temp <<= 1;
}
if (mod != n-1 && temp % 2 == 0) {
return false;
}
}
return true;
}
int inverse(int a, int m) {
a = mod(a, m);
if (a == 1) {
return 1;
}
return mod((1 - m * inverse(m % a, a)) / a, m);
}
void gcdext(int &g, int &x, int &y, int a, int b) {
if (b == 0) { g = a; x = 1; y = 0; }
else
{ gcdext(g, y, x, b, a % b); y = y - (a / b) * x; }
}

14
REP(i,N) phi[i] = i; // Calculating euler Totient function.
FOR(i,2,N) if(phi[i] == i) for(int j = i ; j < N ; j += i) phi[j] -= phi[j]/i;

Data - Structures
Segment Tree Fenwick Tree
struct Tournament {
int T[off << 1];
void init(int val) { REP(i,(off<<1)) T[i]=val; }
void update(int x,int val) {
for ( x += off ; x ; x >>= 1 ) T[x] = max(T[x],val);
}
int query( int lo, int hi, int a = 0, int b = off, int x = 1 ) {
if( a >= hi || b <= lo ) return -INF;
if( a >= lo && b <= hi ) return T[x];
return max( query( lo, hi, a, (a+b)/2, 2*x ), query( lo, hi, (a+b)/2, b, 2*x+1 ) );
}
}T;
struct Fenwick {
int F[Max];
void init(int val) { REP(i,Max) F[i] = val; }
void update(int x,int val) {
for ( ++x ; x < Max ; x += x&-x ) F[x] += val ;
}
int query (int x){
int sum = 0;
for ( ++x ; x ; x -= x&-x ) sum += F[x]; return sum;
}
int get_idx(int k) {
int p,ret;
for (p = ret =0;(1 << p) < Max && F[1<<p] < k;++p);--p; // Get the Highest Bit.
for ( ; p >= 0 ; --p )
if ( F[ret | (1<<p)] < k ) ret |= (1<<p) , k -= F[ret];
return ret;
}
}F;

Balanced Tree - Treap


struct Treap {
int val, priority, maxVal, size;
Treap * left;
Treap * right; // left, right;
Treap() {
val = priority = maxVal = size = 0;
left = right = 0;
}

15
Treap(int _val, int _priority, int _maxVal, int _size) {
val = _val;
maxVal = _maxVal;
size = _size;
priority = _priority;
left = right = 0;
}
};
int SZ(Treap* &t) {
return t ? t->size : 0;
}
int MAX(Treap* &t) {
return t ? t->maxVal : 0;
}
void Adjust(Treap* &T) {
T->size
= 1 + SZ(T->left) + SZ(T->right);
T->maxVal = max(T->val, max(MAX(T->left),MAX(T->right)));
}
void rotateLeft(Treap* &T) {
Treap * t = T->left;
T->left = t->right ; Adjust(T);
t->right = T;
Adjust(t);
T = t;
}
void rotateRight(Treap* &T) {
Treap * t = T->right;
T->right = t->left ; Adjust(T);
t->left = T;
Adjust(t);
T = t;
}
void Balance(Treap* &T) {
if(T->left) {
if(T->left->priority > T->priority) rotateLeft(T);
}
if(T->right) {
if(T->right->priority > T->priority) rotateRight(T);
}
}
void insert(Treap* &T, int val, int where, int pri) {
if(!T) T = new Treap(val,pri,val,1);
else {
if(SZ(T->right) >= where) {
insert(T->right,val,where,pri);
}
else if(max(T->val,MAX(T->right)) > val) {
insert(T->right,val,where,pri);
}
else insert(T->left,val,where-SZ(T->right)-1,pri);
Adjust(T); Balance(T);
}
}

16

String Algorithms
int pkmp[MAXN];
bool KMP(char *ptn, int m, char *txt, int n) {
void preKmp(char *ptn, int m) {
int i = 0, j = 0;
int i, j;
preKmp(ptn, m);
i = 0;
while (j < n) {
j = pkmp[0] = -1;
while (i > -1 && ptn[i] != txt[j])
while (i < m) {
i = pkmp[i];
while (j > -1 && ptn[i] != ptn[j])
i++;
j = pkmp[j];
j++;
i++;
j++;
if (i >= m) {
if (ptn[i] == ptn[j])
cout << j <<endl;return true;
pkmp[i] = pkmp[j];
// i = pkmp[i];
else
}
pkmp[i] = j;
}
}
return false;
}

Suffix array. ( log2 ) time, 16 bytes/char overhead.


// Input: text, N
// Output: sa[] is a sorted list of offsets to all non-empty suffixes,
// lcp[i] = length of longest common prefix of text+sa[i] and text+sa[i+1]
char text[MAX]; long long key[MAX]; int N, sa[MAX], rank[MAX], *lcp=(int*)key;
struct Cmp { bool operator()(int i, int j) const { return key[i]<key[j]; } };
void build() {
for (int i = 0; i < N; i++) { sa[i] = i; key[i] = text[i]; }
sort(sa, sa+N, Cmp());
for (int K = 1; ; K *= 2) {
for (int i = 0; i < N; i++)
rank[sa[i]] = i>0 && key[sa[i-1]]==key[sa[i]] ? rank[sa[i-1]] : i;
if (K >= N) break;
for (int i = 0; i < N; i++)
key[i] = rank[i] * (N+1LL) + (i+K < N ? rank[i+K]+1 : 0);
sort(sa, sa+N, Cmp());
}
for (int i = 0, k = 0; i < N; i++) {
if (k > 0) k--;
if (rank[i] == N-1) { lcp[N-1] = -1; k = 0; continue; }
int j = sa[rank[i]+1];
while (text[i+k] == text[j+k]) k++;
lcp[rank[i]] = k;
}
}

17

Games
Grundy numbers. For a two-player, normal-play (last to move wins) game on a graph (, ):
() = mex({() : (, ) }), where mex() = min{ > 0 : }. is losing iff () = 0.
Sums of games.
Player chooses a game and makes a move in it. Grundy number of a position is xor of grundy
numbers of positions in summed games.
Player chooses a non-empty subset of games (possibly, all) and makes moves in all of them. A
position is losing iff each game is in a losing position.
Player chooses a proper subset of games (not empty and not all), and makes moves in all chosen
ones. A position is losing iff grundy numbers of all games are equal.
Player must move in all games, and loses if cant move in some game. A position is losing if
any of the games is in a losing position.
Mis`
ere Nim. A position with pile sizes 1 , 2 , . . . , > 1, not all equal to 1, is losing iff 1 2
= 0 (like in normal nim.) A position with piles of size 1 is losing iff is odd.

Linear algebra
Determinant of a Matrix
/*
* Determinant of a matrix % p.
* P can be a prime or a power of a single prime.
*/
int b[200][200],n;
int deter(int p) {
int coeff, r2, ret = 1;
REP (i,n) REP (j,n) b[i][j] = mod(b[i][j], p);
REP (i,n) {
if (count_if(b[i] + i, b[i] + n, bind2nd(equal_to<int>(), 0)) == n - i) {
return 0;
}
int g = p;
FOR (j,i,n) g = __gcd(g, b[i][j]);
ret = (int)((((LL)(ret)) * g) % p);
FOR (j,i,n) b[i][j] /= g;
FOR (j,i,n) if (__gcd(b[i][j], p) == 1) {
/* j can act as the pivot */
if (j != i) {
ret = (int)((((LL)(ret)) * (p - 1)) % p);
FOR (k,i,n) swap(b[k][i], b[k][j]);
}
/* now the normal elimination procedure */
FOR (j,i+1,n) {
if (b[i][j]) {
coeff = inverse(b[i][j]);// Get inverse of b[i][i].
//euclide(b[i][i], p, coeff, r2);

18
coeff = (int)((((LL)(coeff)) * b[i][j]) % p);
FOR(k,i,n){
b[k][j]=(int)(b[k][j]-((LL(b[k][i])) * coeff)) % p;
if (b[k][j] < 0) b[k][j] += p;
}
}
}
break;
}
ret = (int)(((LL(ret))*b[i][i])%p);
}
return ret;
}

Rank of Boolean Matrix


a[] == Array of Vectors. [long long.]
int ret = n;
REP(i,n) {
if(a[i] == 0) ret--;
last = a[i] & -a[i];
FOR(j,i+1,n) {
if(a[j] & last) a[j] ^= a[i];
}
}
// ret == Rank of the Matrix. Rank is the size of largest set of independent vectors in a.

Notes /
f[A,k] = A + A^2 + A^3 + A^4 + ... + A^k
f[A,k] = f[A,k-1] * (1 + A) - f[A,k-2] * A
int axbmodc(int a, int b,int c) { // Solves a*x = b (mod c)
return a ? (axbmodc(c % a, (a - b % a) % a, a) * c + b) / a : 0;
}
typedef long double LD;
#define MAXN 200
// ret = Inv(arr) Inverse of the matrix -- O(n^3) Gaussean Jordan Elimination
void findInverse(LD arr[MAXN][MAXN],LD ret[MAXN][MAXN],int N){
LD temp[MAXN][2*MAXN];
REP(i,N)REP(j,N)temp[i][j]=arr[i][j]; //not to disturb values in arr
REP(i,N)REP(j,N){
if(i!=j)temp[i][j+N]=0.0l;
else temp[i][j+N]=1.0l;
}
REP(y,N){
int maxRow=y;
FOR(y2,y+1,N) if(fabs(temp[y2][y])>fabs(temp[maxRow][y])) maxRow=y2;
REP(i,2*N)swap(temp[maxRow][i],temp[y][i]);
LD base = temp[y][y];

19

assert(fabs(base)>1e-9);
FOR(y2,y+1,N){
LD factor = temp[y2][y]/base;
REP(x,2*N) temp[y2][x]-=(factor*temp[y][x]);
}
}
for(int y=N-1;y>=0;y--){
LD c=temp[y][y];
REP(y2,y){
for(int x=2*N-1;x>y-1;x--){
temp[y2][x] -= temp[y][x] * temp[y2][y] / c;
}
}
temp[y][y]/=c;
FOR(x,N,2*N)temp[y][x]/=c;
}
REP(i,N)FOR(j,N,2*N)ret[i][j-N]=temp[i][j];
return;
}

Trie [Can be changed to Integer / Strings etc.]


/* Basic Trie implementation.
* Time complexity of insertion => O(l)
* Time complexity of search => O(l)
* Assumes all character are lower case.
*/
class trie {
public:
trie *child[26];
trie() {
REP (i,26) child[i] = NULL;
}
void insert(char *word) {
if (word[0]) {
if (!child[word[0] - a]) {
child[word[0] - a] = new trie;
}
child[word[0] - a]->insert(word + 1);
}
}
bool find(char *word) {
if (word[0]) {
if (!child[word[0] - a]) {
return false;
}
return child[word[0] - a]->find(word + 1);
}
return true;
}
};

20

Geometry
Picks theorem. = /2 + 1, where is the area of a lattice polygon, is number of lattice
points inside it, and is number of lattice points on the boundary. Number of lattice points minus
one on a line segment from (0, 0) and (, ) is gcd(, ).
= + = || || cos()
= = || || sin()
3D: = ( , , )
Line + = through (1 , 1 ) and (2 , 2 ): = 1 2 , = 2 1 , = 1 + 1 .
Half-plane to the left of the directed segment : + > .
Normal vector: (, ). Direction vector: (, ). Perpendicular line: + = .
1
(1 2 2 1 , 1 2 2 1 ).
Point of intersection of 1 + 1 = 1 and 2 + 2 = 2 is 1 2
2 1
Distance from line + + = 0 to point (0 , 0 ) is |0 + 0 + |/ 2 + 2 .
)( )|
Distance from line to (for any dimension): |(||
.
Point-line segment distance:
if (dot(B-A, P-A) < 0) return dist(A,P);
if (dot(A-B, P-B) < 0) return dist(B,P);
return fabs(cross(P,A,B) / dist(A,B));

.
Projection of point onto line is
Projection of (0 , 0 ) onto line + = is (0 , 0 ) +
1
Projection of the origin is 2 +
2 (, ).

1
(, ),
2 +2

where = 0 0 .

Segment-segment intersection. Two line segments intersect if one of them contains an endpoint
of the other segment, or each segment straddles the line, containing the other segment ( straddles
line if and are on the opposite sides of .)
Circle-circle and circle-line intersection.
a = x2 - x1;
b = y2 - y1;
c = [(r1^2 - x1^2 - y1^2) - (r2^2 - x2^2 - y2^2)] / 2;
d = sqrt(a^2 + b^2);
if not |r1 - r2| <= d <= |r1 + r2|, return "no solution"
if d == 0, circles are concentric, a special case
// Now intersecting circle (x1,y1,r1) with line ax+by=c
Normalize line: a /= d; b /= d; c /= d;
// d=sqrt(a^2+b^2)
e = c - a*x1 - b*y1;
h = sqrt(r1^2 - e^2);
// check if r1<e for circle-line test
return (x1, y1) + (a*e, b*e) +/- h*(-b, a);

Circle from 3 points (circumcircle). Intersect two perpendicular bisectors. Line perpendicular
to + = has the form + = . Find by substituting midpoints coordinates.

Angular bisector of angle is line , where = ||


+ ||
.

Center of incircle of triangle is at the intersection of angular bisectors, and is ++


+ ++
+

2
, where , , are lengths of sides, opposite to vertices , , . Radius = ++ .
++

Counter-clockwise rotation around the origin. (, ) ( cos sin , sin + cos ).


90-degrees counter-clockwise rotation: (, ) (, ). Clockwise: (, ) (, ).
3D rotation by ccw angle around axis n: r = r cos + n(n r)(1 cos ) + (n r) sin
Plane equation from 3 points. (, , ) = , where is normal: = ( ) ( ).

21

3D figures
Sphere

Volume = 34 3 , surface area = 42


= sin cos , = sin sin , = cos , [, ], [0, ]
Spherical section Volume = 2 ( /3), surface area = 2
Pyramid
Volume = 13

Cone
Volume = 13 2 , lateral surface area = 2 + 2

Area of a simple polygon. 12 1


=0 ( +1 +1 ), where = 0 , = 0 .
Area is negative if the boundary is oriented clockwise.
Winding number. Shoot a ray from given point in an arbitrary direction. For each intersection of
ray with polygons side, add +1 if the side crosses it counterclockwise, and 1 if clockwise.
Convex Hull
bool operator <(Point a, Point b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
// Returns convex hull in counter-clockwise order.
// Note: the last point in the returned list is the same as the first one.
vector<Point> ConvexHull(vector<Point> P) {
int n = P.size(), k = 0; vector<Point> H(2*n);
sort(P.begin(), P.end());
for (int i = 0; i < n; i++)
{ while (k >= 2 && cross(H[k-2], H[k-1], P[i]) <= 0) k--; H[k++] = P[i]; }
for (int i = n-2, t = k+1; i >= 0; i--)
{ while (k >= t && cross(H[k-2], H[k-1], P[i]) <= 0) k--; H[k++] = P[i]; }
H.resize(k);
return H;
}

Computational Geometry
inline T dotp(const Line &l, const complex<T> &p) {
return dotp(l.second - l.first, p - l.first);
}
inline T crossp(const Line &l, const complex<T> &p) {
return crossp(l.second - l.first, p - l.first);
}
pair<Point, long double> getCircle(Point p1, Point p2, Point p3) {
Line L1 = MP(p1,p2);
L1.first = p1 + p2;
L1.first /= 2.0;
L1.second = L1.first + rotate(L1.second - L1.first,90.0);
Line L2(p2,p3);
L2.first = p2 + p3;
L2.first /= 2.0;
L2.second = L2.first + rotate(L2.second - L2.first, 90.0);
Point center = intersectionPointLine(L1,L2);
return MP(center, ABS(center-p1));
}
/*
* Closest pair of points.
* Complexity: O(n*log(n))
* returns INF if number of points < 2.

22
*/
long double closestDistance (Point *p, int n) {
if (n <= 1) return INF;
sort(p, p + n, compare);
map<long double, set<long double> > m;
m[p[0].real()].insert(p[0].imag());
long double h = INF, x, y, dist, hh;
for(int i = 1; i < n; ++i) {
hh = (long double)(sqrt(h) + 1);
map< long double, set<long double> >::iterator sbeg = m.upper_bound(p[i].real() - hh);
for(map<long double, set<long double> >::iterator mit = sbeg; mit != m.end(); ++mit) {
set<long double>::iterator ybeg = (*mit).second.upper_bound( p[i].imag() - hh );
set<long double>::iterator yend = (*mit).second.upper_bound( p[i].imag() + hh - 1);
for (set<long double>::iterator sit = ybeg; sit!=yend; ++sit) {
x = (*mit).first, y = (*sit);
dist = (x - p[i].real())*(x - p[i].real())+
(y - p[i].imag())*(y - p[i].imag());
if (dist < h) {
h = dist;
hh = (long double)(sqrtl(h) + 1);
}
}
}
m[ p[i].real() ].insert(p[i].imag());
}
return sqrtl(h);
}
/*
* Polar angle
* Returns an angle in the range [0, 2*Pi) of a given Cartesian point.
* If the point is (0,0), -1.0 is returned.
*/
long double polarAngle(Point p ) {
if(D_EQ(p.real(), 0) && D_EQ(p.imag(), 0)) return -1.0;
long double res = arg(p);
if ( res < 0 ) {
res += 4.0 * acos(0);
}
return res;
}
/*
* Point inside polygon
* Returns true iff p is inside or on the edge.
* The behavior in case of on the edge can be modified easily..
* Complexity: O(n).
*/
bool pointInPoly(Point p, Point *poly, int n) {
long double ang = 0.0, pi = 2.0*acosl(0);
for( int i = n - 1, j = 0; j < n; i = j++ ) {
Point v = poly[i] - p, w = poly[j] - p;
long double va = polarAngle(v), wa = polarAngle(w), xx = wa - va;

23
if(va < -0.5 || wa
// POINT IS ON
return true;
ang += pi;
continue;
}
if( xx < -pi ) ang
else if( xx > pi )
else ang += xx;

< -0.5 || D_EQ(ABS(xx),pi)) {


THE EDGE

+= xx + 2.0 * pi;
ang += xx - 2.0 * pi;

}
return (ang * ang > 1.0);
}
complex<long double> reflection(const Line &l1,const complex<long double> &p) {
complex<long double> l=l1.second - l1.first;
complex<long double> r(-1.0 * l.imag(), l.real());
long double len = norm(r), d = pointLineDistance(l1, p);
r *= 2.0 * d;
r /= len;
if(D_EQ(pointLineDistance(l1, p + r), d)) return p + r;
return p - r;
}
inline complex<long double> rotate(const complex<long double> &p, long double theta) {
theta = theta * acosl(0) / 90.0;
return complex<long double> (p.real() * cosl(theta) - p.imag() * sinl(theta),
p.real() * sinl(theta) + p.imag() * cosl(theta));
}
long double closestDistance2d(const Segment &s1,const Segment &s2){
Vector u=s1.second-s1.first,v=s2.second-s2.first,w=s1.first-s2.first;
long double a=dotp(u,u),b=dotp(u,v),c=dotp(v,v),d=dotp(u,w),e=dotp(v,w);
long double D=a*c-b*b;
long double sc,sN,sD=D;
long double tc,tN,tD=D;
if(ABS(D) < EPS){
sN=0.0;sD=1.0;tN=e;tD=c;
}
else {
sN=b*e-c*d;
tN=a*e-b*d;
if(sN < 0.0){sN=0.0;tN=e;tD=c;}
else if(sN > sD){sN=sD;tN=e+b;tD=c;}
}
if(tN < 0.0){
tN=0.0;
if(-d < 0.0){sN=0.0;}
else if (-d > a){sN = sD;}
else {sN = -d;sD = a;}
}
else if(tN > tD){
tN=tD;
if ((-d + b) < 0.0){sN = 0;}
else if ((-d + b) > a){sN = sD;}
else {sN = (-d + b);sD = a;}
}

24
sc = ((sN>=0.0?sN:-1.0*sN) < 1e-6 ? 0.0 : sN /
tc = ((tN>=0.0?tN:-1.0*tN) < 1e-6 ? 0.0 : tN /
complex<long double> dP(w.real() + sc*u.real()
w.imag() + sc*u.imag()
return ABS(dP);

sD);
tD);
- tc*v.real(),
- tc*v.imag());

}
long double area(const Triangle &t) {
return ABS(t.a.real() * (t.b.imag() - t.c.imag()) +
t.b.real() * (t.c.imag() - t.a.imag()) +
t.c.real() * (t.a.imag() - t.b.imag())) / 2.0;
}
pair<Point,long double> inCircle(const Triangle &t) {
long double bc = norm(t.c - t.b), ab = norm(t.b - t.a), ac = norm(t.c - t.a);
Point res((t.a.real() * bc + t.b.real() * ac + t.c.real() * ab),
(t.a.imag() * bc + t.b.imag() * ac + t.c.imag() * ab));
res /= (ab + bc + ac);
return make_pair(res, 2.0*area(t) / (ab + bc + ac));
}
Point orthoCenter(const Triangle &t) {
Line bc;bc.first = t.b;bc.second = t.c;
Line A_bc = perpendicular(bc, t.a);
Line ab;ab.first = t.a;ab.second = t.b;
Line C_ab = perpendicular(ab, t.c);
return intersectionPointLine(A_bc, C_ab);
}
pair<Point, long double> circumCircle(const Triangle &t) {
return getCircle(t.a, t.b, t.c);
}
/*
* Returns a triangle with given side lengths.
* The vertices of the new triangle are (0,0), (a, 0) and third point in first quadrant
*/
Triangle triangleFromSideLength(long double a, long double b, long double c) {
Point p1(0.0, 0.0), p2(a, 0.0);
long double cos_theta = (a*a + b*b - c*c) / (2*a*b);
long double sin_theta = sqrtl(1.0 - cos_theta*cos_theta);
Point p3(b*cos_theta, b*sin_theta);
Triangle res = {p1,p2,p3};
return res;
}
inline Point rotate(Point p,double theta){
theta = theta*acos(0)/90;
return Point(p.x*cos(theta) - p.y*sin(theta),p.x*sin(theta)+p.y*cos(theta));
}
// Kunals Stuff
template <class T>

25
class point {
public:
T x, y;
point(T _x, T _y) { x = _x; y = _y; }
point() { x =0; y = 0; }
point operator-(const point &b) { return point(x-b.x, y-b.y); }
T operator*(const point &b) { return (x*b.x + y*b.y); } // Dot Product
T operator^(const point &b) { return x*b.y - y*b.x; }
static double linePointDist(point &a, point &b, point &c, bool isSegment) {
double dis = ((b-a)^(c-a)) / dist(a, b);
if (isSegment) {
T dot1 = (c-b)*(b-a);
if (dot1 > 0) return dist(b, c);
T dot2 = (c-a)*(a-b);
if (dot2 > 0) return dist(c, a);
}
return abs(dis);
}
static double dist(const point &a, const point &b) {
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
static T areaOfPolygon(vector<point> &A) {
int n = SZ(A);
T area = 0;
FOR(i, 1, n-1) {
area += (A[i] - A[0]) ^ (A[i+1] - A[0]);
}
return (abs(area) / 2.0);
}
static point lineIntersection(point &a, point &b, point &c, point &d) {
T A1 = b.y-a.y, B1 = a.x - b.x, C1 = A1*a.x + B1*a.y;
T A2 = d.y-c.y, B2 = c.x - d.x, C2 = A2*c.x + B2*c.y;
T det = A1*B2 - B1*A2;
if (det == 0) { } // Parallel Lines
return point((B2*C1 - B1*C2) / det, (A1*C2 - A2*C1) / det);
}
/*
bool isInBounds(point &a, point &b) {
return (x>=min(a.x,b.x) && x<=max(a.x,b.x) &&
y>=min(a.y,b.y) && y<=max(a.y,b.y));
}
*/
bool isInBounds(point &a, point &b) {
return (min(a.x,b.x)-x<1e-6 && x-max(a.x,b.x)<1e-6 &&
min(a.y,b.y)-y<1e-6 && y-max(a.y,b.y)<1e-6);
}
};

You might also like