ICPC Notebook

Embed Size (px)

Citation preview

  • 8/10/2019 ICPC Notebook

    1/25

    1Turing Machine, IIIT HyderabadTeam Reference Material

    December 9th, 2011.

    Template

    /* Author : Turing Machine */

    #include

    #include

    #include

    #include

    #include

    #include

    #include #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    using namespace std;

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

    #define REP(i,n) FOR(i,0,n)

    #define PB push_back

    #define INF 1000000000

    #define ALL(x) x.begin(),x.end()

    #define LET(x,a) __typeof(a) x(a)

    #define IFOR(i,a,b) for(LET(i,a);i!=(b);++i)

    #define EACH(it,v) IFOR(it,v.begin(),v.end())

    typedef pair PI;

    typedef vector VI;typedef long long LL;

    .vimrc=========================================

    set shiftwidth=3

    set makeprg=g++\ %\ -Wall

    map :w :make

    map :cn

    imap

    set cindent

    autocmd BufNewFile *.cpp r ~/start.cpp

    set wrapscan

    =========================================

    DOs and DONTs -

    1. Check the Array Sizes [Each and Everyone of them.]2. Overflows - Check for overflow in the code.3. Take input till EOF always.

    4. Truncate/round decimals.5. If a wrong answer comes, then FIND a case where it goes wrong.

  • 8/10/2019 ICPC Notebook

    2/25

    2

    Graph Theory

    Topological Sort

    //tOrd = topologicalOrder

    //tSort = topologicalSort

    #define MAXN 200000int n,visited[MAXN];

    vector 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 reverseGraph[MAXN];

    void getComponent(int i, vector &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;

    }

  • 8/10/2019 ICPC Notebook

    3/25

    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]

  • 8/10/2019 ICPC Notebook

    4/25

    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 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 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));

    }

  • 8/10/2019 ICPC Notebook

    5/25

    5

    int bfs() {

    fill(ALL(Layers),-1);

    Layers[sink] = 0;

    queue 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 60000VI graph[Max];

    int visited[Max], match[Max], pos[Max], track;

    int dfs(int i) {

  • 8/10/2019 ICPC Notebook

    6/25

    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];

  • 8/10/2019 ICPC Notebook

    7/25

    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

  • 8/10/2019 ICPC Notebook

    8/25

    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 E; vector 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 > 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

  • 8/10/2019 ICPC Notebook

    9/25

    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;

    i f ( i = = n - 1 ) {

  • 8/10/2019 ICPC Notebook

    10/25

    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 T = [tij], where tij is the number of multiedges between i andj, for i=j , and tii =degi. Number of spanning trees of a graph is equal to the determinant of amatrix obtained by deleting anyk-th row and k-th column from T. IfGis a multigraph and e is anedge ofG, then the number(G) of spanning trees ofGsatisfies recurrence(G) =(Ge)+(G/e),whenG eis the multigraph obtained by deleting e, andG/e is the contraction ofG by e (multipleedges arising from the contraction are preserved.)

    Euler tours. Euler tour in an undirected graph exists iff the graph is connected and each vertex hasan 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 m: let w be the most-preferred woman towhom he has not yet proposed, and propose m to w. Ifw is free, or is engaged to someone whomshe prefers less than m, match m with w, 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 x y add edges (x, y) and (y, x). The formula is satisfiable iffx andx are in distinctSCCs, for allx. To find a satisfiable assignment, consider the graphs SCCs in topological order fromsinks 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.

  • 8/10/2019 ICPC Notebook

    11/25

    11

    Combinatorics

    Sumsn

    k=0 k = n(n+ 1)/2 b

    k=a k= (a +b)(b a + 1)/2nk=0 k

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

    k=0 k3 =n2(n+ 1)2/4

    n

    k=0

    k4 = (6n5 + 15n4 + 10n3

    n)/30

    n

    k=0

    k5 = (2n6 + 6n5 + 5n4

    n2)/12

    nk=0 x

    k = (xn+1 1)/(x 1) nk=0 kxk = (x (n+ 1)xn+1 +nxn+2)/(x 1)21 +x+x2 + = 1/(1 x)

    Binomial coefficients(nk

    )=

    (n1k

    )+(n1k1

    )

    Number of ways to pick a multiset of size k from n elements:(n+k1

    k

    )

    Number ofn-tuples of non-negative integers with sum s:(s+n1n1

    ), at most s:

    (s+nn

    )

    Number ofn-tuples of positive integers with sum s:(s1n1

    )

    Number of lattice paths from (0, 0) to (a, b), restricted to east and north steps:(a+b

    a

    )

    Harmonic Progression.n

    k=11/k = ln(n) + 0.577215664901532 + 1/(2n) 1/(12n2) + 1/(120n4) . . .

    (nr

    )modulo p.

    (nr

    )mod pequals the product of

    (niri

    )mod pwhere

    n1n2 . . . and r1r2 . . . are the digits ofnand r when written in base p.(e.g -

    (213

    )mod 17 equals

    (10

    )*(43

    )mod 17.)

    Derangements. Number of permutations of n = 0, 1, 2, . . . elements without fixed points is1, 0, 1, 2, 9, 44, 265, 1854, 14833, . . . Recurrence: Dn = (n1)(Dn1 + Dn2) = nDn1 + (1)n.Corollary: number of permutations with exactly k fixed points is

    (nk

    )Dnk.

    Stirling numbers of 1st kind. sn,k is (1)nk times the number of permutations ofn elementswith exactlyk permutation cycles.|sn,k|=|sn1,k1| + (n 1)|sn1,k|.

    nk=0 sn,kx

    k =xn

    Stirling numbers of 2nd kind. Sn,k is the number of ways to partition a set ofn elements intoexactly k non-empty subsets. Sn,k =Sn1,k1+kSn1,k. Sn,1=Sn,n= 1. x

    n =n

    k=0 Sn,kxk

    Bell numbers. Bn is the number of partitions ofn elements. B0, . . .= 1, 1, 2, 5, 15, 52, 203, . . .Bn+1

    =n

    k=0(n

    k)B

    k=

    n

    k=1Sn,k

    . Bell triangle: Br=a

    r,1=a

    r1,r1, a

    r,c= a

    r1,c1+a

    r,c1.

    Number Theory

    Linear diophantine equation. ax +by = c. Let d = gcd(a, b). A solution exists iffd|c. If (x0, y0)is any solution, then all solutions are given by (x, y) = (x0 +

    bd

    t, y0 ad t),t Z. To find some solution(x0, y0), use extended GCD to solve ax0+by0=d = gcd(a, b), and multiply its solutions by

    cd

    .

    Linear diophantine equation in nvariables: a1x1+ + anxn= c has solutions iff gcd(a1, . . . , an)|c.To find some solution, let b= gcd(a2, . . . , an), solve a1x1+by = c, and iterate with a2x2+

    = y.

    Multiplicative inverse ofa modulo m: xinax+my = 1, or a(m)1 (mod m).

    Chinese Remainder Theorem. Systemxai (mod mi) fori = 1, . . . , n, with pairwise relatively-

  • 8/10/2019 ICPC Notebook

    12/25

    12

    prime mi has a unique solution modulo M = m1m2 . . . mn: x = a1b1Mm1

    + +anbn Mmn (mod M),where bi is modular inverse of

    Mmi

    modulomi.

    System xa (mod m), xb (mod n) has solutions iffab (mod g), where g= gcd(m, n). Thesolution is unique modulo L = mn

    g , and equals: xa+T(b a)m/g b +S(a b)n/g (mod L),

    where Sand Tare integer solutions ofmT+nS= gcd(m, n).

    Prime-counting function. (n) = |{p n : pis prime}|. n/ ln(n) < (n) < 1.3n/ ln(n).(1000) = 168, (106) = 78498, (109) = 50 847 534. n-th primen ln n.Fermat primes. A Fermat prime is a prime of form 22

    n

    + 1. The only known Fermat primes are 3,5, 17, 257, 65537. A number of form 2n + 1 is prime only if it is a Fermat prime.

    Perfect numbers. n > 1 is called perfect if it equals sum of its proper divisors and 1. Even n isperfect iffn = 2p1(2p 1) and 2p 1 is prime (Mersennes). No odd perfect numbers are yet found.Carmichael numbers. A positive composite n is a Carmichael number (an1 1 (mod n) for alla: gcd(a, n) = 1), iffnis square-free, and for all prime divisors pofn, p

    1 divides n

    1.

    Number/sum of divisors. (pa11 . . . pakk ) =

    kj=1(aj+ 1). (p

    a11 . . . p

    akk ) =

    kj=1

    paj+1

    j 1

    pj1 .

    Eulers phi function. (n) =|{mN, m n, gcd(m, n) = 1}|.(mn) = (m)(n)gcd(m,n)

    (gcd(m,n)) . (pa) =pa1(p 1). d|n (d) =

    d|n (

    nd

    ) =n.

    Eulers theorem. a(n) 1 (mod n), if gcd(a, n) = 1.Wilsons theorem. p is prime iff (p 1)! 1 (mod p).Mobius function. (1) = 1. (n) = 0, ifn is not squarefree. (n) = (1)s, ifn is the product ofsdistinct primes. Let f, Fbe functions on positive integers. If for all nN, F(n) =d|n f(d), thenf(n) =d|n (d)F(nd ), and vice versa. (n) =

    d|n (d)

    nd

    .

    d|n (d) = 1.

    Iff is multiplicative, then

    d|n (d)f(d) =

    p|n(1 f(p)),

    d|n (d)2f(d) =

    p|n(1 +f(p)).

    Primitive roots. If the order ofg modulo m (min n > 0: gn 1 (mod m)) is (m), then g iscalled a primitive root. IfZm has a primitive root, then it has ((m)) distinct primitive roots. Zmhas a primitive root iffmis one of 2, 4, pk, 2pk, wherep is an odd prime. IfZm has a primitive rootg, then for alla coprime tom, there exists unique integeri = indg(a) modulo(m), such thatg

    i a(mod m). indg(a) has logarithm-like properties: ind(1) = 0, ind(ab) = ind(a) + ind(b).

    Ifp is prime anda is not divisible by p, then congruence xn a (mod p) has gcd(n, p 1) solutionsifa

    (p1)/gcd(n,p1)

    1 (mod p), and no solutions otherwise. (Proof sketch: let g be a primitive root,and gi a (mod p), gu x (mod p). xn a (mod p) iffgnu g i (mod p) iffnui (mod p).)Pythagorean triples. Integer solutions ofx2 +y2 = z2 All relatively prime triples are given by:x = 2mn,y = m2 n2, z = m2 +n2 where m > n, gcd(m, n) = 1 and m n (mod 2). All othertriples are multiples of these. Equation x2 +y2 = 2z2 is equivalent to (x+y

    2 )2 + ( xy

    2 )2 =z2.

    Postage stamps/McNuggets problem. Let a, b be relatively-prime integers. There are exactly12

    (a1)(b1) numbersnotof formax +by(x, y 0), and the largest is (a1)(b1)1 =abab.Fermats two-squares theorem. Odd prime p can be represented as a sum of two squares iffp

    1 (mod 4). A product of two sums of two squares is a sum of two squares. Thus, nis a sum of

    two squares iff every prime of form p= 4k+ 3 occurs an even number of times in ns factorization.

  • 8/10/2019 ICPC Notebook

    13/25

    13

    Utilities - Number Theory.

    LL calculateModulo(LL a, LL b, LL n) {

    LL res = 0;

    while (b) {

    i f ( b & 1 ) {

    --b; res = (res + a) % n;}

    else{

    b >>= 1;a = 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

  • 8/10/2019 ICPC Notebook

    14/25

    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 = hi || b = lo && b

  • 8/10/2019 ICPC Notebook

    15/25

    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);}

    }

  • 8/10/2019 ICPC Notebook

    16/25

    16

    String Algorithms

    int pkmp[MAXN];

    void preKmp(char *ptn, int m) {

    int i, j;

    i = 0 ;j = pkmp[0] = -1;

    while (i < m) {

    while (j > -1 && ptn[i] != ptn[j])

    j = pkmp[j];

    i++;

    j++;

    if (ptn[i] == ptn[j])

    pkmp[i] = pkmp[j];

    else

    pkmp[i] = j;

    }

    }

    bool KMP(char *ptn, int m, char *txt, int n) {

    i n t i = 0 , j = 0 ;

    preKmp(ptn, m);while (j < n) {

    while (i > -1 && ptn[i] != txt[j])

    i = pkmp[i];

    i++;

    j++;

    if (i >= m) {

    cout

  • 8/10/2019 ICPC Notebook

    17/25

    17

    Games

    Grundy numbers. For a two-player, normal-play (last to move wins) game on a graph (V, E):G(x) = mex({G(y) : (x, y)E}), where mex(S) = min{n 0 :nS}. xis losing iffG(x) = 0.Sums of games.

    Player chooses a game and makes a move in it. Grundy number of a position is xor of grundynumbers of positions in summed games.

    Player chooses a non-empty subset of games (possibly, all) and makes moves in all of them. Aposition 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 al l chosenones. 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 ifany of the games is in a losing position.

    Misere Nim. A position with pile sizes a1, a2, . . . , an 1, not all equal to 1, is losing iffa1 a2 an= 0 (like in normal nim.) A position with n piles of size 1 is losing iffnis 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(), 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);

  • 8/10/2019 ICPC Notebook

    18/25

    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];

  • 8/10/2019 ICPC Notebook

    19/25

    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;

    }

    };

  • 8/10/2019 ICPC Notebook

    20/25

    20

    Geometry

    Picks theorem. I=A B/2 + 1, where Ais the area of a lattice polygon, I is number of latticepoints inside it, and B is number of lattice points on the boundary. Number of lattice points minusone on a line segment from (0, 0) and (x, y) is gcd(x, y).

    a b= axbx+ayby =|a| |b| cos()a b= axby aybx =|a| |b| sin()3D: a b= (aybz azby, azbx axbz, axby aybx)Line ax+by = c through A(x1, y1) and B(x2, y2): a= y1 y2, b= x2 x1, c= ax1+by1.Half-plane to the left of the directed segment AB: ax+by c.Normal vector: (a, b). Direction vector: (b, a). Perpendicular line:bx+ay = d.Point of intersection ofa1x+b1y=c1 and a2x+b2y = c2 is

    1a1b2a2b1

    (c1b2 c2b1, a1c2 a2c1).Distance from line ax+by+c= 0 to point (x0, y0) is|ax0+by0+c|/

    a2 +b2.

    Distance from line AB to P(for any dimension): |(AP)(BP)||AB|

    .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 Conto line AB is ABACABAB

    AB.Projection of (x0, y0) onto line ax+by = c is (x0, y0) +

    1a2+b2

    (ad, bd), where d= c ax0 by0.Projection of the origin is 1

    a2+b2(ac, bc).

    Segment-segment intersection. Two line segments intersect if one of them contains an endpointof the other segment, or each segment straddles the line, containing the other segment (AB straddleslinel ifA and B are on the opposite sides ofl.)

    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|

  • 8/10/2019 ICPC Notebook

    21/25

    21

    3D figuresSphere Volume V = 4

    3r3, surface area S= 4r2

    x= sin cos , y = sin sin , z= cos , [, ], [0, ]Spherical section VolumeV =h2(r h/3), surface area S= 2rhPyramid Volume V = 1

    3hSbase

    Cone Volume V = 13

    r2h, lateral surface area S=r

    r2 +h2

    Area of a simple polygon. 12

    n1i=0(xiyi+1 xi+1yi), where xn = x0, yn= y0.

    Area is negative if the boundary is oriented clockwise.

    Winding number. Shoot a ray from given point in an arbitrary direction. For each intersection ofray with polygons side, add +1 if the side crosses it counterclockwise, and 1 if clockwise.Convex Hull

    bool operator = 2 && cross(H[k-2], H[k-1], P[i]) = 0; i--)

    { while (k >= t && cross(H[k-2], H[k-1], P[i])

  • 8/10/2019 ICPC Notebook

    22/25

    22

    */

    long double closestDistance (Point *p, int n) {

    if (n ::iterator sbeg = m.upper_bound(p[i].real() - hh);

    for(map::iterator mit = sbeg; mit != m.end(); ++mit) {

    set::iterator ybeg = (*mit).second.upper_bound( p[i].imag() - hh );

    set::iterator yend = (*mit).second.upper_bound( p[i].imag() + hh - 1);

    for (set::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);

    i f ( r e s < 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);

    f o r ( i n t 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;

  • 8/10/2019 ICPC Notebook

    23/25

    23

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

    // POINT IS ON THE EDGE

    return true;

    ang += pi;

    continue;

    }

    if( xx < -pi ) ang += xx + 2.0 * pi;else if( xx > pi ) ang += xx - 2.0 * pi;

    else ang += xx;

    }

    return (ang * ang > 1.0);

    }

    complex reflection(const Line &l1,const complex &p) {

    complex l=l1.second - l1.first;

    complex 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 rotate(const complex &p, long double theta) {

    theta = theta * acosl(0) / 90.0;

    return complex (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;}

    }

  • 8/10/2019 ICPC Notebook

    24/25

    24

    sc = ((sN>=0.0?sN:-1.0*sN) < 1e-6 ? 0.0 : sN / sD);

    tc = ((tN>=0.0?tN:-1.0*tN) < 1e-6 ? 0.0 : tN / tD);

    complex dP(w.real() + sc*u.real() - tc*v.real(),

    w.imag() + sc*u.imag() - tc*v.imag());

    return ABS(dP);

    }

    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 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 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

  • 8/10/2019 ICPC Notebook

    25/25

    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 &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=min(a.y,b.y) && y