ECIGMA - Notebook (C++) Codes For ACM ICPC

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 18

ECIGMA - Notebook (C++)

Codes for ACM ICPC


Grupo de Maratonistas
Escuela Colombiana de Ingenierı́a Julio Garavito
05–03–2017

Contents 6.6 Rabin-Karp (AC feb-2015) . . . . . . . . . . 13

1 Parsing. 2 7 Geometry. 13
1.1 Parser . . . . . . . . . . . . . . . . . . . . . 2 7.1 Basics . . . . . . . . . . . . . . . . . . . . . 13
7.2 Closest Pair Problem . . . . . . . . . . . . . 14
2 Structures. 2 7.3 Convex-Hull . . . . . . . . . . . . . . . . . . 14
2.1 Union find . . . . . . . . . . . . . . . . . . . 2 7.4 Formulas . . . . . . . . . . . . . . . . . . . 14
2.2 Segment Tree . . . . . . . . . . . . . . . . . 2
2.3 Segment Trees 2 . . . . . . . . . . . . . . . 3 8 Mathematics. 15
2.4 Full Segment Tree . . . . . . . . . . . . . . 3 8.1 GCD . . . . . . . . . . . . . . . . . . . . . . 15
2.5 Fenwick Trees - Pending check . . . . . . . 3 8.2 Extended Euclid . . . . . . . . . . . . . . . 15
2.6 C-Bigint (AC feb-2015) . . . . . . . . . . . 3 8.3 Cycle Finding . . . . . . . . . . . . . . . . . 15
8.4 Sieve of Erathostenes . . . . . . . . . . . . . 15
3 Ad-hoc 4 8.5 Pollard-Rho . . . . . . . . . . . . . . . . . . 15
3.1 Dates . . . . . . . . . . . . . . . . . . . . . 4 8.6 Totient function . . . . . . . . . . . . . . . . 16
3.2 Dice . . . . . . . . . . . . . . . . . . . . . . 4 8.7 FFT (AC feb-2015) . . . . . . . . . . . . . . 16
3.3 Bitwise (AC feb-2015) . . . . . . . . . . . . 4 8.8 Primes. . . . . . . . . . . . . . . . . . . . . 16
3.4 Modular product . . . . . . . . . . . . . . . 5 8.9 Combinatorics. . . . . . . . . . . . . . . . . 17

4 Classic ones. 5 9 Solution not working? 18


4.1 Longest Increasing Subsequence (AC feb-
2015) . . . . . . . . . . . . . . . . . . . . . . 5 10 Bibliography 18
4.2 Sliding minimum . . . . . . . . . . . . . . . 5
4.3 TSP . . . . . . . . . . . . . . . . . . . . . . 6

5 Graphs. 6
5.1 TopoSort . . . . . . . . . . . . . . . . . . . 6
5.2 TopoSort 2 . . . . . . . . . . . . . . . . . . 6
5.3 Tarjan . . . . . . . . . . . . . . . . . . . . . 6
5.4 Kosaraju . . . . . . . . . . . . . . . . . . . 7
5.5 SCC compression . . . . . . . . . . . . . . . 7
5.6 Dijkstra . . . . . . . . . . . . . . . . . . . . 7
5.7 FW . . . . . . . . . . . . . . . . . . . . . . 8
5.8 Kruskal . . . . . . . . . . . . . . . . . . . . 8
5.9 Edmonds - Karp . . . . . . . . . . . . . . . 9
5.10 Dinic (AC 19/04/2016) . . . . . . . . . . . 9
5.11 Bipartite-matching . . . . . . . . . . . . . . 9
5.12 Hungarian . . . . . . . . . . . . . . . . . . . 10
5.13 Adjoint matrix power. . . . . . . . . . . . . 11

6 Strings. 12
6.1 Knuth-Morris-Pratt . . . . . . . . . . . . . 12
6.2 Suffix array and LCP . . . . . . . . . . . . . 12
6.3 Longest common substring . . . . . . . . . 12
6.4 Booth . . . . . . . . . . . . . . . . . . . . . 12
6.5 Manacher . . . . . . . . . . . . . . . . . . . 12

1
1 Parsing. 2 Structures.
1.1 Parser 2.1 Union find
splitstrip(char* s,char c) splits s into substrings AC - Rewritten by ocin
using ca as delimiter. It auto strips each substring and 1 # define LIM 1005
auto ignores empty substrings. It modifies s. 2 # define SET ( arr , x ) memset ( arr , x , sizeof ( arr ) )
rmchar(char* s,char c) removes all occurrences of c 3 int p [ LIM ] , rk [ LIM ] , nsets ;
4 void dsinit ( int _n ) { nsets = _n ; SET (p , -1) ; SET ( rk
in s.
, 0) ;}
tonum(char* s) assumes s to be an integer. 5 int parent ( int x ) {
6 if ( p [ x ]== -1) return x ;
7 else return p [ x ]= parent ( p [ x ]) ;
1 typedef vector < char * > vs ; 8 }
2 9 bool dsunion ( int x , int y ) {
3 vs splitstrip ( char * s , char c ) { 10 x = parent ( x ) ; y = parent ( y ) ;
4 int i , tok =1 , sp =0; 11 if ( x != y ) {
5 vs l ; 12 if ( rk [ x ] > rk [ y ]) swap (x , y ) ;
6 for ( i =0; s [ i ]; i ++) { 13 if ( rk [ x ]== rk [ y ]) rk [ y ]+=1;
7 if ( s [ i ]== c ) tok =1 , s [ sp ]=0; 14 p [ x ]= y ; nsets - -;
8 else if ( s [ i ]!= ’ ’) { sp = i +1; if ( tok ) l . pushb ( s + 15 }
i ) , tok =0; } 16 return ( x != y ) ;
9 else if ( s [ sp ]!= ’ ’) sp = i ; 17 }
10 }
11 if (i >0 && s [i -1]== ’\ n ’) s [i -1]=0;
12 return l ;
13 } 2.2 Segment Tree
14
15 void rmchar ( char * s , char a ) { f(a,b): O(1)
16 int i =0 , j =0;
17 while ( s [ i ]) { 1. Must be associative like +,*,max,min.
18 if ( s [ i ]!= a ) s [ j ++]= s [ i ];
19 i ++; build(i,lo,hi): O(n log n)
20 }
21 s [ j ]=0; 1. Building is necessary before updating or answering
22 }
queries.
23
24 large tonum ( char * s ) {
25 int i ; large n =0;
2. Call build(0,0,alen) to build a segment tree based
26 i =! isdigit ( s [0]) ; on a.
27 while ( s [ i ]) n =10* n + s [ i ++] - ’0 ’;
28 return ( s [0]== ’ - ’) ? -n : n ; 3. Re-building is much faster than updating one by one.
29 }
query(i,lo,hi): O(log n)
1. lo < hi MUST hold ( < strictly).
2. Call query(0,lo,hi) to get f(A[lo..hi)).
update(i,v): O(log n)
1. Updates a[i]=v.

1 int a [ LEN ] , tree [2* LEN ] , Lo [2* LEN ] , Hi [2* LEN ] , Ind [
LEN ];
2
3 # define PA ( i ) ((( i ) -1) /2)
4 # define L ( i ) (2*( i ) +1)
5 # define R ( i ) (2*( i ) +2)
6
7 int f ( int a , int b ) { return max (a , b ) ;}
8
9 void build ( int i , int lo , int hi ) {
10 Lo [ i ]= lo ; Hi [ i ]= hi ;
11 if ( hi - lo ==1) Ind [ lo ]= i , tree [ i ]= a [ lo ];
12 else {
13 build ( L ( i ) ,lo ,( lo + hi ) /2) ;
14 build ( R ( i ) ,( lo + hi ) /2 , hi ) ;
15 tree [ i ] = f ( tree [ L ( i ) ] , tree [ R ( i ) ]) ;
16 }
17 }
18

2
19 int query ( int i , int lo , int hi ) { // pre : lo [ i ] <= 25 for (; l < r ; l > >= 1 , r > >= 1) {
lo <= hi <= hi [ i ] 26 if ( l &1) apply ( l ++ , value ) ;
20 if ( Hi [ i ] - Lo [ i ]==1 || Hi [ i ]== hi && Lo [ i ]== lo ) 27 if ( r &1) apply ( - -r , value ) ;
return tree [ i ]; 28 }
21 int mid =( Lo [ i ]+ Hi [ i ]) /2; 29 build ( l0 ) ;
22 if ( lo >= mid ) return query ( R ( i ) ,lo , hi ) ; 30 build ( r0 - 1) ;
23 if ( hi <= mid ) return query ( L ( i ) ,lo , hi ) ; 31 }
24 return f ( query ( L ( i ) ,lo , mid ) , query ( R ( i ) ,mid , hi ) 32
); 33 int query ( int l , int r ) {
25 } 34 l += n , r += n ;
26 35 push ( l ) ;
27 void update ( int i , int v ) { 36 push ( r - 1) ;
28 a [ i ]= v ; i = Ind [ i ]; tree [ i ]= v ; 37 int res = -2 e9 ;
29 for ( i = PA ( i ) ;i >=0; i = PA ( i ) ) tree [ i ]= f ( tree [ L ( i ) ] , 38 for (; l < r ; l > >= 1 , r > >= 1) {
tree [ R ( i ) ]) ; 39 if ( l &1) res = max ( res , t [ l ++]) ;
30 } 40 if ( r &1) res = max ( t [ - - r ] , res ) ;
41 }
42 return res ;
43 }
2.3 Segment Trees 2
2.5 Fenwick Trees - Pending check
1 // http :// codeforces . com / blog / entry /18051
2 int len , tlen ; 1 - - - - - - - - - - - - - - - Check pending
3 large a [ LEN ] , t [4* LEN ]; ---------------------------
4 2 - - - - - - - - - - - - - - - Comments pending
5 void pre () { ------------------------
6 int i ; 3 void increase ( int i , int delta ) {
7 for ( tlen =1; tlen < len ; tlen < <=1) ; 4 for (; i < sz ; i |= i + 1) tree [ i ] += delta ;
8 loop (i ,0 , len ) t [ tlen + i ] = a [ i ]; 5 }
9 rev (i , tlen -1 ,1) t [ i ] = t [i < <1] + t [i < <1|1]; 6
10 } 7 int sum ( int ind ) {
11 8 int sum = 0;
12 large query ( int l , int r ) { 9 while ( ind >=0) {
13 large tl =0 , tr =0; 10 sum += tree [ ind ];
14 for ( l += tlen , r += tlen ; l < r ; l > >=1 , r > >=1) { 11 ind &= ind + 1;
15 if ( l &1) tl = tl + t [ l ++]; 12 ind - -;
16 if ( r &1) tr = tr + t [ - - r ]; 13 }
17 } 14 return sum ;
18 return tl + tr ; 15 }
19 } 16
20 17 int getsum ( int left , int right ) {
21 void modify ( int i , int x ) { 18 return sum ( right ) - sum ( left -1) ;
22 for ( t [ i += tlen ]= x ; i >1; i > >=1) 19 }
23 t [i > >1]= t [ i ]+ t [ i ^1];
24 } 2.6 C-Bigint (AC feb-2015)
2.4 Full Segment Tree Considerations

1 // http :// codeforces . com / blog / entry /18051 1. The greater the Base, the lesser the memory needed
2 void apply ( int p , int value ) { and the faster the algorithms run. However, high
3 t [ p ] += value ; Bases may lead overflow. Use 10^4.
4 if ( p < n ) d [ p ] += value ;
5 } *(a,b): O(n log n)
6
7 void build ( int p ) { 1. Needs polymult-FFT implementation (35 lines of
8 while ( p > 1) p > >= 1 , t [ p ] = max ( t [p < <1] , t [p
code).
< <1|1]) + d [ p ];
9 }
10
2. Don’t use it unless numbers are really large: higher
11 void push ( int p ) { than Base^10000.
12 for ( int s = h ; s > 0; --s ) {
13 int i = p >> s ; 1 # define Base 10000
14 if ( d [ i ] != 0) { 2 # define SZ 1000005
15 apply (i < <1 , d [ i ]) ; 3
16 apply (i < <1|1 , d [ i ]) ; 4 typedef long long int large ;
17 d [ i ] = 0; 5 typedef vector < large > bigint ;
18 } 6 int aa [ SZ ] , ab [ SZ ] , ac [ SZ ];
19 } 7
20 } 8 bigint bbsum ( bigint &a , bigint & b ) {
21 9 int i , ca =0;
22 void inc ( int l , int r , int value ) { 10 bigint c ;
23 l += n , r += n ; 11 loop (i ,0 , a . size () ) { c . pushb (( a [ i ]+ b [ i ]+ ca ) % Base
24 int l0 = l , r0 = r ; ) ; ca =( a [ i ]+ b [ i ]+ ca ) / Base ; }

3
12 loop (i , a . size () ,b . size () ) { c . pushb (( b [ i ]+ ca ) % 3 Ad-hoc
Base ) ; ca =( b [ i ]+ ca ) / Base ; }
13 if ( ca >0) c . pushb ( ca ) ;
14 return c ;
3.1 Dates
15 }
AC
16
17 bigint operator +( bigint &a , bigint & b ) { return a . 1 # define y first
size () <= b . size () ? bbsum (a , b ) : bbsum (b , a ) ;} 2 # define m second . first
18 3 # define d second . second
19 bigint operator *( bigint &a , bigint & b ) { // n * n 4 typedef pair < int , int > ii ;
20 int i ,j , csz = a . size () + b . size () ; 5 typedef pair < int , ii > date ;
21 setmem ( ac ,0) ; 6 int mdays
22 loop (i ,0 , a . size () ) loop (j ,0 , b . size () ) ac [ i + j ]+= [12]={31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31};
a [ i ]* b [ j ]; 7 int macum
23 loop (i ,0 , csz ) { [13]={0 ,31 ,59 ,90 ,120 ,151 ,181 ,212 ,243 ,273 ,304 ,334 ,365};
24 ac [ i +1] += ac [ i ]/ Base ;
25 ac [ i ] %= Base ; 8 int leaps ( int y1 , int y2 ) { return y2 /4 - y2 /100+ y2
26 } /400 -( y1 /4 - y1 /100+ y1 /400) ;}
27 while ( csz >0 && ac [ csz -1]==0) csz - -; 9
28 bigint c ; 10 int days ( date d0 , date d1 ) { // Days from d0 to d1
29 loop (i ,0 , csz ) c . pushb ( ac [ i ]) ; ( can be negative )
30 return c ; 11 // Warning : Months are [1..12] indexed .
31 } 12 int between , flag =1;
32 13 if ( d0 > d1 ) { flag = -1; swap ( d0 , d1 ) ;}
33 bigint operator *( bigint &a , bigint & b ) { // n log n 14 between = 365*( d1 .y - d0 . y ) + macum [ d1 .m -1] -
34 int i ; macum [ d0 .m -1]+ d1 .d - d0 . d ;
35 loop (i ,0 , a . size () ) aa [ i ]= a [ i ]; 15 between += leaps ( d0 .y -( ii ( d0 .m , d0 . d ) <= ii (2 ,29) )
36 loop (i ,0 , b . size () ) ab [ i ]= b [ i ]; ,
37 int csz = polymult ( aa , ab , ac , a . size () ,b . size () ) ; 16 d1 .y -( ii ( d1 .m , d1 . d ) <= ii (2 ,29) ) ) ;
// see docs . 17 return between * flag ;
38 loop (i ,0 , csz ) { 18 }
39 ac [ i +1] += ac [ i ]/ Base ;
40 ac [ i ] %= Base ;
41 }
42 while ( csz >0 && ac [ csz -1]==0) csz - -; 3.2 Dice
43 bigint c ;
44 loop (i ,0 , csz ) c . pushb ( ac [ i ]) ; AC
45 return c ; 1 // index [0..5]
46 } 2 char moves [4]={ ’u ’ , ’l ’ , ’d ’ , ’r ’ }; // Moves rolling
47 in a table .
48 void printbigint ( bigint & a ) { 3 int nextt [6][6][4]; // next_top = nextt [ curr_top
49 int i , z = log10 ( Base ) ; ][ curr_front ][ mov ]
50 char s [10]; 4 int nextf [6][6][4]; // next_front = nextf [ curr_top
51 sprintf (s , " %%0% dlld " ,z ) ; ][ curr_front ][ mov ]
52 if ( a . size () >0) { 5
53 printf ( " % lld " ,a [ a . size () -1]) ; 6 void pre () {
54 rev (i , a . size () -2 ,0) printf (s , a [ i ]) ; 7 int t ,f ,m , sides [4] , i ;
55 } else printf ( " 0 " ) ; 8 loop (t ,0 ,6) {
56 printf ( " \ n " ) ; 9 sides [0] = t <3? ( t +1) %3 : (7 - t ) %3;
57 } 10 sides [1] = t <3? ( t +2) %3 : (6 - t ) %3;
11 sides [2] = 5 - sides [0]; sides [3] = 5 - sides [1];
12 loop (m ,0 ,4) loop (f ,0 ,4) {
13 nextt [ t ][ sides [ f ]][ m ] = sides [( f + m ) %4];
14 nextf [ t ][ sides [ f ]][ m ] = m ==0? 5 - t : m ==2? t :
sides [ f ];
15 }
16 }
17 }

3.3 Bitwise (AC feb-2015)


AC
1 int fsb ( int n ) { return n &( - n ) ;} // first_set_bit
(n)
2 int fsb ( unsint n ) { return n &((~ n ) -1) ;} //
first_set_bit ( n )
3 ( n & ( - n ) ) == n <--> n ==0 || n =2^ i || n = -2^ i
4
5 large bitreverse ( large n , int l ) {
6 large m =0 , i ;
7 loop (i ,0 , l ) m =( m < <1) |(( n > > i ) &1) ;

4
8 return m ; 4 Classic ones.
9 }
10 void bitprint ( large n ) { if (n >1) bitprint (n > >1) ;
printf ( " % d " ,n &1) ; }
4.1 Longest Increasing Subsequence (AC
feb-2015)
lis-log(): O(n log n)
3.4 Modular product
1. Computes the length of a lis of t[0..tsz).
AC
1 large MOD =1000000007; 2. Needs b array to work.
2 large mulmod ( large a , large b ) {
3 large ans =0; a %= MOD ; b %= MOD ; 3. Optional: to build Longest Strictly Increasing Subse-
4 while ( a !=0) { quences use upperBound instead of lowerBound.
5 if ( a &1) ans =( ans + b ) % MOD ; a > >=1; b =( b < <1) % MOD ;
} 4. Optional: to get an array with the lis indices, use
6 return ans ; prev, bindex and llis arrays.
7 }
8 // bigMod computes ( a ^ n ) % MOD in log ( n ) 5. Optional: to get the length of a lis ending at each
9 large bigMod ( large a , large n ) {
index, use lisAt array.
10 if ( n ==0) return 1;
11 if ( n ==1) return a % MOD ;
12 large t = bigMod (a , n /2) ; 1 int t [ SZ ] , b [ SZ ] , tsz , bsz ;
13 t = mulmod (t , t ) ; 2 int prev [ SZ ] , bindex [ SZ ] , llis [ SZ ];
14 if ( n &1) t = mulmod (t , ( a % MOD ) ) ; 3 int lisAt [ SZ ];
15 return t 4
16 } 5 void lis_log () { // n log n
6 int i , j ; bsz =0;
7 loop (i ,0 , tsz ) {
8 j = lower_bound (b , b + bsz , t [ i ]) ; // see docs .
9 bsz += j == bsz ;
10 b [ j ]= t [ i ];
11 // optional calculus to get lis list :
12 bindex [ j ] = i ;
13 prev [ i ] = j ==0? -1: bindex [j -1];
14 // optional calculus for length of a lis
ending at i :
15 lisAt [ i ] = j +1;
16 }
17 }
18
19 void prev2llis () { // build lis indices list :
20 int i , j = bsz ;
21 for ( i = bindex [ bsz -1]; i != -1; i = prev [ i ]) llis [ - - j
]= i ;
22 }
23
24 void lis_2 () { // n * n
25 int i , j ; bsz =0; loop (i ,0 , tsz ) len [ i ] = 1;
26 loop (i ,0 , tsz ) loop (j ,0 , i )
27 if ( t [ j ] < t [ i ] && len [ j ]+1 > len [ i ]) len [ i ] =
len [ j ]+1;
28 }

4.2 Sliding minimum


AC.
1 int sliding_min () { // gets the min of s [ i .. i + n )
for every i
2 int ans = INFINITY ,i , l ;
3 priority_queue < ii , deque < ii > , greater < ii > > q ;
4 loop (i ,0 , n ) q . push ( ii ( s [ i ] , i ) ) ;
5 loop (i ,0 , ssz +1 - n ) {
6 while ( q . top () . y < i ) q . pop () ;
7 l = q . top () . x ;
8 // at this point , l = min ( s [ i .. i + n ) )
9 ans = min ( ans , l ) ;
10 q . push ( ii ( lcp [ i + n ] , i + n ) ) ;
11 }
12 return ans ;
13 }

5
4.3 TSP 5 Graphs.
Rewrite
5.1 TopoSort
1 // code taken from Felix Halim : CP3 online
material 1 int cont , in [ LIM ];
2 int i , j , TC , xsize , ysize , n , x [11] , y [11] , dist 2 char car [25] , res [25];
[11][11] , memo [11][1 << 11]; // Karel + max 3 bool vis [25];
10 beepers 4 vector < int > adjList [ LIM ];
3 5 // in - degree toposort , backtracking to visit all
4 int tsp ( int pos , int bitmask ) { // bitmask stores possible
the visited coordinates 6 // topological orderings
5 if ( bitmask == (1 << ( n + 1) ) - 1) 7 bool toposort ( int nodo , int n ) {
6 return dist [ pos ][0]; // return trip to close 8 int b , i ;
the loop 9 bool ans = false , t ;
7 if ( memo [ pos ][ bitmask ] != -1) 10 res [ n ]= car [ nodo ];
8 return memo [ pos ][ bitmask ]; 11 if ( n == cont -1) {
9 int ans = 2000000000; 12 putchar ( res [0]) ;
10 for ( int nxt = 0; nxt <= n ; nxt ++) // O ( n ) here 13 FOR (i , 1 , cont ) printf ( " % c " , res [ i ]) ;
11 if ( nxt != pos && !( bitmask & (1 << nxt ) ) ) // 14 putchar ( ’\ n ’) ;
if coordinate nxt is not visited yet 15 return true ;
12 ans = min ( ans , dist [ pos ][ nxt ] + tsp ( nxt , 16 }
bitmask | (1 << nxt ) ) ) ; 17 vis [ nodo ]= true ;
13 return memo [ pos ][ bitmask ] = ans ; 18 b = adjList [ nodo ]. size () ;
14 } 19 FOR (i , 0 , b ) {
15 20 in [ adjList [ nodo ][ i ]] -=1; // take out edges
16 int main () { 21 }
17 scanf ( " % d " , & TC ) ; 22 FOR (i , 0 , cont ) {
18 while ( TC - -) { 23 if (! vis [ i ] && in [ i ]==0) {
19 scanf ( " % d % d " , & xsize , & ysize ) ; // these two 24 t = toposort (i , n +1) ;
values are not used 25 ans = ans || t ;
20 scanf ( " % d % d " , & x [0] , & y [0]) ; 26 }
21 scanf ( " % d " , & n ) ; 27 }
22 for ( i = 1; i <= n ; i ++) // karel ’s position 28 FOR (i , 0 , b ) {
is at index 0 29 in [ adjList [ nodo ][ i ]]+=1; // puts edges again
23 scanf ( " % d % d " , & x [ i ] , & y [ i ]) ; 30 }
24 for ( i = 0; i <= n ; i ++) // build distance 31 vis [ nodo ]= false ;
table 32 res [ n ]=0;
25 for ( j = 0; j <= n ; j ++) 33 return ans ;
26 dist [ i ][ j ] = abs ( x [ i ] - x [ j ]) + abs ( y [ i ] 34 }
- y [ j ]) ; // Manhattan distance
27 memset ( memo , -1 , sizeof memo ) ; 5.2 TopoSort 2
28 printf ( " The shortest path has length % d \ n " ,
tsp (0 , 1) ) ; // DP - TSP
1 list < int > ts ;
29 }
2 // based on Felix Halim : CP3 online material
30 return 0;
3 void TopoSort2 ( int u ) {
31 }
4 int j , v ;
5 dfs_num [ u ]=1; // visited
6 loop (j , 0 , ( int ) AL [ u ]. size () ) {
7 v = AL [ u ][ j ];
8 if ( dfs_num [ v ] == 0)
9 TopoSort2 ( v ) ;
10 }
11 ts . pushf ( u ) ;
12 }
13
14 // inside main ( void )
15 list < int >:: iterator it ;
16 ts . clear () ;
17 SET ( dfs_num , 0) ;
18 loop (i , 0 , n ) {
19 if ( dfs_num [ i ]==0)
20 TopoSort ( i ) ;
21 }
22 for ( it ; it != ts . end () ; it ++)
23 printf ( " % d " , * it ) ;
24 putchar ( ’\ n ’) ;

5.3 Tarjan
1 // taken from : Competitive Programming 2
2 void a r t i c u l a t i o n P o i n t A n d B r i d g e ( int u ) {
3 dfs_low [ u ] = dfs_num [ u ] = d f s N u m b e r Co u n t e r ++;

6
4 for ( int j = 0; j < ( int ) AdjList [ u ]. size () ; j 30 Kosaraju (a , 2) ;
++) { 31 }
5 ii v = AdjList [ u ][ j ]; 32 }
6 if ( dfs_num [ v . first ]== DFS_WHITE ) { // tree edge 33 printf ( " % d \ n " , SCC ) ;
7 dfs_parent [ v . first ] = u ;
8 if ( u == dfsRoot ) rootChildren ++; // 5.5 SCC compression
special case
9 a r t i c u l a t i o n P o i n t A n d B r i d g e ( v . first ) ; 1 int n , m , p [ LIM ] , lo [ LIM ] , num [ LIM ] , dfscount ,
10 if ( dfs_low [ v . first ] >= dfs_num [ u ]) SCC ;
11 a r t i c u l a t i o n _ v e r t e x [ u ] = true ; 2 int indeg [ LIM ];
12 if ( dfs_low [ v . first ] > dfs_num [ u ]) // for 3 bool vis [ LIM ];
bridge 4 di s , AL [ LIM ] , AL2 [ LIM ];
13 printf ( " Edge (% d , % d ) is a bridge \ n " , u , 5 set < int > tm1 [ LIM ];
v . first ) ; 6
14 dfs_low [ u ] = min ( dfs_low [ u ] , dfs_low [ v . 7 void tarjan ( int u ) {
first ]) ; 8 int v , j ;
15 // updated dfs_low [ u ] 9 lo [ u ]= num [ u ]= dfscount ++;
16 } else if ( v . first != dfs_parent [ u ]) 10 s . pb ( u ) ;
17 dfs_low [ u ] = min ( dfs_low [ u ] , dfs_num [ v . 11 vis [ u ]= true ;
first ]) ; 12 loop (j , 0 , ( int ) AL [ u ]. size () ) {
18 } 13 v = AL [ u ][ j ];
19 } 14 if ( num [ v ]==0) tarjan ( v ) ;
20 15 if ( vis [ v ]) lo [ u ]= min ( lo [ u ] , lo [ v ]) ;
21 // inside int main () 16 }
22 d f s N u m b e r C o u n t er = 0; dfs_num . assign (V , 17 if ( lo [ u ]== num [ u ]) {
DFS_WHITE ) ; 18 // printf (" SCC =% d \ n " , SCC ) ;
23 dfs_low . assign (V , 0) ; 19 do {
24 dfs_parent . assign (V , 0) ; 20 v = s . back () ; s . pop_back () ;
25 a r t i c u l a t i o n _ v e r t e x . assign (V , 0) ; 21 // printf ("% d \ n " , v +1) ;
26 printf ( " Bridges :\ n " ) ; 22 vis [ v ]=0;
27 for ( int i = 0; i < V ; i ++) 23 p [ v ]= SCC ;
28 if ( dfs_num [ i ] == DFS_WHITE ) { 24 } while ( u != v ) ;
29 dfsRoot = i ; rootChildren = 0; 25 SCC ++;
30 articulationPointAndBridge (i); 26 }
31 a r t i c u l a t i o n _ v e r t e x [ dfsRoot ]=( rootChildren 27 }
>1) ; 28
32 } 29 // Inside main
33 printf ( " Articulation Points :\ n " ) ; 30 loop (i , 0 , n ) num [ i ]= lo [ i ]=0 , vis [ i ]= false ;
34 for ( int i = 0; i < V ; i ++) 31 dfscount =1; SCC =0;
35 if ( a r t i c u l a t i o n _ v e r t e x [ i ]) 32 loop (i , 0 , n ) {
36 printf ( " Vertex % d \ n " , i ) ; 33 if ( num [ i ]==0) tarjan ( i ) ;
34 }
5.4 Kosaraju 35 loop (i , 0 , n ) {
36 loop (j , 0 , ( int ) AL [ i ]. size () ) {
1 typedef vector < int > vi ; 37 v = AL [ i ][ j ];
2 int n ; 38 if ( p [ i ]!= p [ v ]) tm1 [ p [ i ]]. insert ( p [ v ]) ;
3 vi AL1 [ LIM ] , AL2 [ LIM ]; 39 }
4 stack < int > s ; 40 }
5 bool vis [ LIM ]; 41 loop (i , 0 , n ) indeg [ i ]=0;
6 42 loop (i , 0 , SCC ) {
7 int Kosaraju ( int u , int pass ) { 43 for ( set < int >:: iterator it = tm1 [ i ]. begin () ; it !=
8 int i , v ; tm1 [ i ]. end () ; it ++) {
9 vi neighbor =( pass ==1) ? AL1 [ u ] : AL2 [ u ]; 44 v =(* it ) ;
10 vis [ u ]=1; 45 // printf ("% d -> % d \ n " , i +1 , v +1) ;
11 loop (i , 0 , ( int ) neighbor . size () ) { 46 AL2 [ i ]. pb ( v ) ; indeg [ v ]+=1;
12 v = neighbor [ i ]; 47 }
13 if (! vis [ v ]) Kosaraju (v , pass ) ; 48 }
14 }
15 if ( pass ==1) s . push ( u ) ; 5.6 Dijkstra
16 }
17 1 priority_queue < ii , vector < ii > , greater < ii > > pq ;
18 // inside int main ( void ) 2 loop (i , 0 , n ) dis [ i ]= INF ; dis [ s ]=0;
19 SET ( vis , 0) ; 3 while (! pq . empty () ) pq . pop () ;
20 while (! s . empty () ) s . pop () ; 4 pq . push ( ii (0 , s ) ) ;
21 loop (i , 0 , n ) { 5 while (! pq . empty () ) {
22 if (! vis [ i ]) Kosaraju (i , 1) ; 6 par = pq . top () ; pq . pop () ;
23 } 7 d = par . X ; u = par . Y ;
24 SET ( vis , 0) ; 8 if (d > dis [ u ]) continue ;
25 SCC =0; 9 loop (j , 0 , ( int ) adjList [ u ]. size () ) {
26 while (! s . empty () ) { 10 ii v = adjList [ u ][ j ];
27 a = s . top () ; s . pop () ; 11 if ( dis [ u ]+ v . Y < dis [ v . X ]) {
28 if (! vis [ a ]) { 12 dis [ v . X ]= dis [ u ] + v . Y ;
29 SCC ++; 13 pq . push ( ii ( dis [ v . X ] , v . X ) ) ;

7
14 } 45 vec . pb ( mp ( sqrt (( x [ i ] - x [ j ]) *( x [ i ] - x [ j ]) +
15 } 46 ( y [ i ] - y [ j ]) *( y [ i ] - y [ j ]) ) , mp (i , j
16 } )));
47 }
5.7 FW 48 }
49 sort ( vec . begin () , vec . end () ) ;
AC 50 suma =0.0; // kruskal begins here
51 for ( it = vec . begin () ; it != vec . end () ; it ++) {
1 // saving the shortest path from i to j 52 if (! isSameSet ( it - > second . first , it - > second .
2 loop (i , 0 , n ) loop (j , 0 , n ) prev [ i ][ j ]= i ; second ) ) {
3 53 suma += it - > first ;
4 loop (k , 0 , n ) loop (i , 0 , n ) loop (j , 0 , n ) { 54 unionSet ( it - > second . first , it - > second .
5 if ( mat [ i ][ j ] > mat [ i ][ k ]+ mat [ k ][ j ]) { second ) ;
6 mat [ i ][ j ] = mat [ i ][ k ] + mat [ k ][ j ]; 55 }
7 prev [ i ][ j ]= prev [ k ][ j ]; 56 }
8 } 57 printf ( " %.2 lf \ n " , suma ) ;
9 } 58
10 59 /*
11 // to print path : void PrintPath 60 SECOND BEST SPANNING TREE IN O ( ELOGV )
12 void PrintPath ( int ori , int dest ) { 61 INSTEAD OF O ( EV )
13 if ( ori != dest ) 62 STEPS :
14 PrintPath ( ori , prev [ ori ][ dest ]) ; 63 1) Run Kruskal ’s Algorithm as normal , saving the
15 printf ( " % d " , dest +1) ; edges as Adjacency List ( AL ) and saving the
16 } edges not included in the MST in another
Adjacency List ( OTHER )
64 2) Precalculate mat [ i ][ j ]= ’ largest edge cost along
5.8 Kruskal the path i - j in AL ( here done with spread ()
function )
65 3) For each edge (u - v ) in OTHER , minimize : cost of
1 typedef vector < ii > vii ;
MST - mat [ u ][ v ] + cost of (u - v ) in OTHER
2 typedef pair < double , ii > dii ;
66 4) The minimum found in 3) is the cost of the
3 typedef vector < dii > vdii ;
second best ST
4
67 */
5 vector < int > pset (1000) , tam (1000) ;
68 typedef pair < int , ii > tri ;
6 int numberOfSets ;
69
7 void initSet ( int _size ) {
70 dii AL [ LIM ];
8 int i ;
71 int t , lim , mat [ LIM ][ LIM ] , curr ;
9 pset . resize ( _size ) ;
72
10 tam . resize ( _size ) ;
73 int p [ LIM ] , rk [ LIM ] , nsets ;
11 numberOfSets = _size ;
74 void dsinit ( int _n ) { nsets = _n ; SET (p , -1) ; SET ( rk
12 FOR (i , 0 , _size ) {
, 0) ;}
13 pset [ i ] = i ;
75 int parent ( int x ) {
14 tam [ i ] = 1;
76 if ( p [ x ]== -1) return x ;
15 }
77 else return p [ x ]= parent ( p [ x ]) ;
16 }
78 }
17 int findSet ( int i ) {
79 bool dsunion ( int x , int y ) {
18 return ( pset [ i ]== i ) ? i :( pset [ i ] = findSet ( pset
80 x = parent ( x ) ; y = parent ( y ) ;
[ i ]) ) ;
81 if ( x != y ) {
19 }
82 if ( rk [ x ] > rk [ y ]) swap (x , y ) ;
20 void unionSet ( int i , int j ) {
83 if ( rk [ x ]== rk [ y ]) rk [ y ]+=1;
21 int x , y ;
84 p [ x ]= y ; nsets - -;
22 x = findSet ( i ) ;
85 }
23 y = findSet ( j ) ;
86 return ( x != y ) ;
24 if ( x == y ) return ;
87 }
25 pset [ x ] = y ;
88
26 tam [ y ] += tam [ x ];
89 void spread ( int u ) {
27 numberOfSets - -;
90 int i , v , w ;
28 }
91 loop (i , 0 , ( int ) AL [ u ]. size () ) {
29 bool isSameSet ( int i , int j ) {
92 v = AL [ u ][ i ]. x ;
30 return findSet ( i ) == findSet ( j ) ;
93 w = AL [ u ][ i ]. y ;
31 }
94 if ( mat [ curr ][ v ] >=0) continue ;
32 int sizeOfSet ( int x ) {
95 mat [ curr ][ v ]= max ( mat [ curr ][ u ] , w ) ;
33 return tam [ x ] = tam [ findSet ( x ) ];
96 spread ( v ) ;
34 }
97 }
35
98 }
36 vdii vec ;
99
37 vdii :: iterator it ;
100 int main ( void ) {
38 double x [ LIM ] , y [ LIM ];
101 int i , n , m , ncasos , caso =0 , nstates , j , a ;
39
102 int roads ;
40 // inside int main ( void )
103 // READ (" A C M C o n t e s t A n d B l a c k o u t 1 0 6 0 0 . txt ") ;
41 initSet ( n ) ;
104 scanf ( " % d " , & ncasos ) ;
42 vec . clear () ;
105 loop ( caso , 0 , ncasos ) {
43 FOR (i , 0 , n ) { // generating edge list
106 scanf ( " % d % d " , &n , & m ) ;
44 FOR (j , i +1 , n ) {

8
107 roads =0; 31 dist [ v ] = dist [ u ]+1;
108 loop (i , 0 , m ) { 32 q . pb ( v ) ; p [ v ]= u ;
109 scanf ( " % d % d % d " , & edge [ i ]. y .x , & edge [ i ]. y . 33 }
y , & edge [ i ]. x ) ; 34 }
110 edge [ i ]. y .y -=1; edge [ i ]. y .x -=1; 35 }
111 } 36 SET ( vis , false ) ; f =0;
112 loop (i , 0 , n ) AL [ i ]. clear () ; 37 augment (t , INF ) ; // puts ("") ;
113 dsinit ( n ) ; 38 maxflow += f ; // printf (" maxflow =% d f =% d \ n " ,
114 t = a = roads =0; maxflow , f ) ;
115 // normal Kruskal ’s for MST 39 } while (f >0) ;
116 sort ( edge , edge + m ) ; 40 return maxflow ;
117 while (t < m ) { 41 }
118 if ( dsunion ( edge [ t ]. y .x , edge [ t ]. y . y ) ) {
119 roads += edge [ t ]. x ; 5.10 Dinic (AC 19/04/2016)
120 AL [ edge [ t ]. y . x ]. pb ( ii ( edge [ t ]. y .y , edge [ t
]. x ) ) ;
121 AL [ edge [ t ]. y . y ]. pb ( ii ( edge [ t ]. y .x , edge [ t 1 di AL [ LIM ];
]. x ) ) ; 2 int AM [ LIM ][ LIM ] , p [ LIM ];
122 } else if ( edge [ t ]. y . x != edge [ t ]. y . y ) { 3 void addEdge ( int a , int b , int c ) {
123 other [ a ++]= edge [ t ]; 4 AL [ a ]. pb ( b ) ; AM [ a ][ b ] = c ;
124 // printf (" - - >% d %d ,% d \ n " , other [a -1]. x , 5 }
other [a -1]. y .x , other [a -1]. y . y ) ; 6 int maxFlowDinic ( int s , int t ) {
125 } 7 int flow = 0 , f , i , u , v ;
126 t ++; 8 di q , nxt ;
127 } 9 while ( true ) {
128 // precal culating mat [ i ][ j ]; 10 q . clear () ; q . pb ( s ) ;
129 loop ( curr , 0 , n ) { 11 SET (p , -1) ; p [ s ] = -2;
130 SET ( mat [ curr ] , -1) ; 12 nxt . clear () ;
131 spread ( curr ) ; 13
132 } 14 while (! q . empty () ) {
133 // here saving the second best ST 15 u = q . front () ; q . pop_front () ;
134 t =0 x3FFFFFFF ; 16 if ( u == t ) break ;
135 loop (i , 0 , a ) { 17 loop (i , 0 , ( int ) AL [ u ]. size () ) {
136 t = min (t , ( roads - mat [ other [ i ]. y . x ][ other [ i 18 v = AL [ u ][ i ];
]. y . y ] + other [ i ]. x ) ) ; 19 if ( v == t && AM [ u ][ v ]) nxt . pb ( u ) ;
137 } 20 if ( p [ v ]== -1 && AM [ u ][ v ]) {
138 printf ( " % d % d \ n " , roads , t ) ; 21 p [ v ]= u ; q . pb ( v ) ;
139 } 22 }
140 return 0; 23 }
141 } 24 }
25 if ( p [ t ] == -1) return flow ;
26
5.9 Edmonds - Karp 27 loop (i , 0 , ( int ) nxt . size () ) {
28 v = t ; u = nxt [ i ];
1 di AL [ LIM ]; 29 if ( AM [ u ][ v ] && p [ u ] >=0) {
2 int AM [ LIM ][ LIM ] , f , s , t ; 30 f = INF ;
3 map < int , int > p , dist ; 31 do {
4 bool vis [ LIM ]; 32 f = min (f , AM [ u ][ v ]) ; v = u ; u = p [ v ];
5 33 } while (u >=0) ;
6 void augment ( int v , int minedge ) { 34 if ( f ==0) continue ;
7 if ( v == s ) { 35 v = t ; u = nxt [ i ];
8 f = minedge ; 36 do {
9 } else if ( p . count ( v ) ) { 37 AM [ u ][ v ] -= f ; AM [ v ][ u ]+= f ;
10 if ( vis [ v ]) { f =0; return ; } 38 v = u ; u = p [ v ];
11 vis [ v ]= true ; 39 } while (u >=0) ;
12 minedge = min ( minedge , AM [ p [ v ]][ v ]) ; 40 flow += f ;
13 augment ( p [ v ] , minedge ) ; 41 }
14 AM [ p [ v ]][ v ] -= f ; 42 }
15 AM [ v ][ p [ v ]] += f ; // printf (" - >% d " , v ) ; 43 }
16 } 44 return flow ;
17 } 45 }
18
19 int EdmondsKarp () { 5.11 Bipartite-matching
20 int maxflow =0 , u , v , i ;
21 di q ; AC
22 do {
23 q . clear () ; dist . clear () ; 1 typedef pair < int , int > ii ;
24 q . pb ( s ) ; dist [ s ]=0; 2 typedef long long ll ;
25 while (! q . empty () ) { 3 typedef vector < int > vi ;
26 u = q . front () ; q . pop_front () ; 4
27 if ( u == t ) break ; 5 int v , match [ LIM ];
28 loop (i , 0 , ( int ) AL [ u ]. size () ) { 6 bool vis [ LIM ];
29 v = AL [ u ][ i ]; 7 vi AL [ LIM ];
30 if ( AM [ u ][ v ] >0 && ! dist . count ( v ) ) { 8

9
9 int Augment ( int x ) { 41 Lmate [ i ] = j ;
10 int j , r ; 42 Rmate [ j ] = i ;
11 if ( vis [ x ]) return 0; 43 mated ++;
12 vis [ x ]= true ; 44 break ;
13 FOR (j , 0 , ( int ) AL [ x ]. size () ) { 45 }
14 r = AL [ x ][ j ]; 46 }
15 if ( match [ r ]== -1 || Augment ( match [ r ]) ) { 47 }
16 match [ r ]= x ; 48
17 return 1; 49 VD dist ( n ) ;
18 } 50 VI dad ( n ) ;
19 } 51 VI seen ( n ) ;
20 return 0; 52 // repeat until primal solution is feasible
21 } 53 while ( mated < n ) {
22 54 // find an unmatched left node
23 // inside int main ( void ) 55 int s = 0;
24 a =0; 56 while ( Lmate [ s ] != -1) s ++;
25 SET ( match , -1) ; 57 // initialize Dijkstra
26 FOR (i , 0 , v ) { 58 fill ( dad . begin () , dad . end () , -1) ;
27 SET ( vis , 0) ; 59 fill ( seen . begin () , seen . end () , 0) ;
28 a += Augment ( i ) ; 60 for ( int k = 0; k < n ; k ++)
29 } 61 dist [ k ] = cost [ s ][ k ] - u [ s ] - v [ k ];
30 printf ( " % d \ n " , a ) ; 62
63 j = 0;
64 while ( true ) {
65 // find closest
5.12 Hungarian 66 j = -1;
67 for ( int k = 0; k < n ; k ++) {
68 if ( seen [ k ]) continue ;
1 # include < bits / stdc ++. h >
69 if ( j == -1 || dist [ k ] < dist [ j ]) j = k ;
2 # define FOR (i , a , b ) for ( i = a ; i < b ; i ++)
70 }
3 # define LIM 205
71 seen [ j ] = 1;
4 # define SET ( mat , a ) memset ( mat , a , sizeof ( mat )
72 // termination condition
)
73 if ( Rmate [ j ] == -1) break ;
5 # define X first
74 // relax neighbors
6 # define Y second
75 i = Rmate [ j ];
7 # define mp make_pair
76 for ( int k = 0; k < n ; k ++) {
8 # define pb push_back
77 if ( seen [ k ]) continue ;
9 # define INF 10000000
78 const double new_dist =
10 using namespace std ;
79 dist [ j ] + cost [ i ][ k ] - u [ i ] -
11 typedef vector < double > VD ;
v [ k ];
12 typedef vector < VD > VVD ;
80 if ( dist [ k ] > new_dist ) {
13 typedef vector < int > VI ;
81 dist [ k ] = new_dist ;
14 typedef pair < int , int > ii ;
82 dad [ k ] = j ;
15 typedef long long ll ;
83 }
16 double cost [ LIM ][ LIM ];
84 }
17 VI Lmate , Rmate ;
85 }
18 int n , r ;
86 // update dual variables
19
87 for ( int k = 0; k < n ; k ++) {
20 double M in C os tM at c hi ng () {
88 if ( k == j || ! seen [ k ]) continue ;
21 // int n = int ( cost . size () ) ; // construct dual
89 i = Rmate [ k ];
feasible solution
90 v [ k ] += dist [ k ] - dist [ j ];
22 int i , j ;
91 u [ i ] -= dist [ k ] - dist [ j ];
23 VD u ( n ) ;
92 }
24 VD v ( n ) ;
93 u [ s ] += dist [ j ];
25 for ( i = 0; i < n ; i ++) {
94 // augment along path
26 u [ i ] = cost [ i ][0];
95 while ( dad [ j ] >= 0) {
27 for ( j = 1; j < n ; j ++) u [ i ] = min ( u [ i ] , cost
96 const int d = dad [ j ];
[ i ][ j ]) ;
97 Rmate [ j ] = Rmate [ d ];
28 }
98 Lmate [ Rmate [ j ]] = j ;
29 for ( j = 0; j < n ; j ++) {
99 j = d;
30 v [ j ] = cost [0][ j ] - u [0];
100 }
31 for ( i =1; i < n ; i ++) v [ j ] = min ( v [ j ] , cost [ i ][
101 Rmate [ j ] = s ;
j ] - u [ i ]) ;
102 Lmate [ s ] = j ;
32 }
103
33 // construct primal solution satisfying
104 mated ++;
complementary slackness
105 }
34 Lmate = VI (n , -1) ;
106
35 Rmate = VI (n , -1) ;
107 double value = 0;
36 int mated = 0;
108 for ( i = 0; i < n ; i ++)
37 for ( i = 0; i < n ; i ++) {
109 value += cost [ i ][ Lmate [ i ]];
38 for ( j = 0; j < n ; j ++) {
110
39 if ( Rmate [ j ] != -1) continue ;
111 return value ;
40 if ( fabs ( cost [ i ][ j ] - u [ i ] - v [ j ]) < 1e -10)
112 }
{

10
113 26 loop (u ,0 , V ) loop (v ,0 , V ) b . m [ u ][ v ]= a . m [ u ][ v ];
114 int main ( void ) { 27 }
115 int i , j ; 28
116 int k ; 29 void mpow ( int n ) {
117 ii p1 [ LIM ] , p2 [ LIM ]; 30 matcpy (m , m2 ) ;
118 while ( scanf ( " % d % d " , &n , & r ) ==2) { 31 int u , v ;
119 FOR (i , 0 , n ) { 32 loop (u ,0 , V ) loop (v ,0 , V ) m . m [ u ][ v ]=( u == v ) ;
120 scanf ( " % d % d " , & p1 [ i ]. X , & p1 [ i ]. Y ) ; 33 while ( n ) {
121 } 34 if ( n %2) m *= m2 ;
122 FOR (i , 0 , r ) { 35 m2 *= m2 , n /=2;
123 scanf ( " % d % d " , & p2 [ i ]. X , & p2 [ i ]. Y ) ; 36 }
124 } 37 }
125 FOR (i , 0 , n ) {
126 FOR (j , 0 , r ) {
127 k = abs ( p2 [ j ]. X - p1 [ i ]. X ) + abs ( p2 [ j ]. Y - p1 [ i ]. Y ) ;
128 cost [ i ][ j ]= k ;
129 }
130 FOR (j , r , n ) cost [ i ][ j ]= INF ;
131 }
132 /* printf (" matriz cost [][]\ n ") ;
133 FOR (i , 0 , n ) {
134 printf (" fila % d :" , i ) ;
135 FOR (j , 0 , r ) {
136 printf (" %.0 lf " , cost [ i ][ j ]) ;
137 }
138 puts ("") ;
139 } */
140 printf ( " % d \ n " , int ( Mi n Co st Ma t ch in g () ) % INF ) ;
141 }
142 return 0;
143 }

5.13 Adjoint matrix power.


mpow(n): O(V 2 log(V + n))

1. Computes m^n in situ.

2. m must be zero-one adjacency matrix, and V must be


the total number of vertices.

3. WIDTH recommended is 31. GWIDTH must be chosen so


that GWIDTH*WIDTH >= LEN holds.

1 typedef struct { int m [ LEN ][ LEN ];} matrix ;


2 matrix m , m2 ;
3
4 # define WIDTH 31
5 # define GWIDTH 5
6 large za [ LEN ][ GWIDTH ] , zb [ LEN ][ GWIDTH ];
7
8 void operator *=( matrix & a , matrix & b ) {
9 int u ,v , j ;
10 loop (u ,0 , V ) {
11 loop (j ,0 , GWIDTH ) za [ u ][ j ]=0;
12 loop (v ,0 , V ) za [ u ][ v / WIDTH ] |= ( a . m [ u ][ v ]) <<
( v % WIDTH ) ;
13 }
14 loop (v ,0 , V ) {
15 loop (j ,0 , GWIDTH ) zb [ v ][ j ]=0;
16 loop (u ,0 , V ) zb [ v ][ u / WIDTH ] |= ( b . m [ u ][ v ]) <<
( u % WIDTH ) ;
17 }
18 loop (u ,0 , V ) loop (v ,0 , V ) {
19 a . m [ u ][ v ] = 0;
20 loop (j ,0 , GWIDTH ) a . m [ u ][ v ] |= (( za [ u ][ j ] & zb
[ v ][ j ]) !=0) ;
21 }
22 }
23
24 void matcpy ( matrix & a , matrix & b ) {
25 int u , v ;

11
6 Strings. 5 i += gap , j += gap ;
6 return (i < len && j < len ) ? pos [ i ] < pos [ j ] : i > j ;
7 }
6.1 Knuth-Morris-Pratt 8
9 void suffixArray ( char * t , int * sa , int tsz ) {
AC 10 int i ,j , k =0;
1 # include < bits / stdc ++. h > 11 if ( tsz <=1) { sa [0]= lcp [0]=0; return ; }
2 # define MAX_N 100010 12 loop (i ,0 , tsz ) sa [ i ]= i , pos [ i ]= t [ i ];
3 using namespace std ; 13 len = tsz , gap =1 , tmp [ tsz -1]= tmp [0]=1;
4 14 while ( tmp [ tsz -1] < tsz ) {
5 char T [ MAX_N ] , P [ MAX_N ]; 15 sort ( sa , sa + tsz , gapcmp ) ;
6 int b [ MAX_N ] , n , m ; 16 loop (i ,1 , tsz ) tmp [ i ]= tmp [i -1]+ gapcmp ( sa [i
7 -1] , sa [ i ]) ;
8 // optimized process 17 loop (i ,0 , tsz ) pos [ sa [ i ]]= tmp [ i ];
9 void kmpPreprocess () { 18 gap < <=1;
10 int j = -1 , i =0; 19 }
11 for ( i =0; i < m ; i ++) { 20 // Optional for LCP :
12 if (j >=0 && P [ i ]== P [ j ]) b [ i ]= b [ j ]; 21 loop (i ,0 , tsz ) if ( pos [ i ]!= tsz ) {
13 else b [ i ]= j ; 22 j = sa [ pos [ i ]];
14 while (j >=0 && P [ i ]!= P [ j ]) j = b [ j ]; 23 while ( t [ i + k ] == t [ j + k ]) ++ k ;
15 j ++; 24 lcp [ pos [ i ] -1] = k ;
16 } 25 if ( k ) --k ;
17 } 26 } // Caution : LCP is valid in range [0 , tsz -1)
18 27 }
19 void kmpSearch () {
20 int i = 0 , j = 0;
21 while ( i < n ) {
22 while ( j >= 0 && T [ i ] != P [ j ]) j = b [ j ];
6.3 Longest common substring
23 i ++; j ++;
24 if ( j == m ) {
EMPTY
25 printf ( " P is found at index % d in T \ n " , i -
j);
26 j = b [ j ];
6.4 Booth
27 }
28 }
AC
29 } 1 char s [ sSZ ] , temp [ sSZ ];
30 2 int f [ sSZ ] , ssz ;
31 /* Find just the first match of the pattern in 3
the text , 4 int booth () {
32 * and return the position of the caracther after 5 // Returns first index of minimum
the match 6 // lexicographic rotation of s [0.. ssz )
33 */ 7 // Uses char temp [0.. ssz ) and
34 int kmpSearch () { 8 // int f [0.. ssz ) for computation
35 int j =0 , i ; 9 int k =0 , j , i ;
36 for ( i =0; i < n ; i ++) { 10 strcpy ( temp , s ) ; strcat (s , temp ) ; SET (f , -1) ;
37 while (j >=0 && T [ i ]!= P [ j ]) j = b [ j ]; 11 loop (j , 1 , 2* ssz ) {
38 if ( j +1== m ) { 12 i = f [j -k -1];
39 return i - j +1; 13 while ( i != -1 && s [ j ] != s [ k + i +1]) {
40 } 14 if ( s [ j ] < s [ k + i +1]) k =j -i -1;
41 j ++; 15 i = f [ i ];
42 } 16 }
43 return -1; 17 if ( i == -1 && s [ j ] != s [ k + i +1]) {
44 } 18 if ( s [ j ] < s [ k + i +1]) k =j -i -1;
45 19 f [j - k ]= -1;
46 int main () { 20 }
47 strcpy (T , " heyhelloyou " ) ; 21 else f [j - k ]= i +1;
48 strcpy (P , " hel " ) ; 22 }
49 n = strlen ( T ) ; 23 return k ;
50 m = strlen ( P ) ; 24 }
51 memset (b ,0 , sizeof b ) ;
52 kmpPreprocess () ;
53 kmpSearch () ;
54 } 6.5 Manacher
1 char text [ LEN ];
6.2 Suffix array and LCP 2 int L [ LEN ] , n ;
3
AC - 26 feb 2015. 4 int manacher () {
5 int N , C =1 , R =2 , i =0 , iMirror , start , end ,
1 int gap , len , pos [ SZ ] , tmp [ SZ ] , sa [ SZ ] , lcp [ SZ ]; diff ;
2 6 if ( n == 0) return 0;
3 bool gapcmp ( int i , int j ) { 7 N = 2* n + 1;
4 if ( pos [ i ]!= pos [ j ]) return pos [ i ] < pos [ j ]; 8 L [0] = 0;

12
9 L [1] = 1; 7 Geometry.
10 int maxLPSLength = 0;
11 int m a x L P S C e n t e r P o s i t i o n = 0;
12 start = end = diff = -1; 7.1 Basics
13 loop (i ,2 , N ) {
14 iMirror = 2* C - i ;
1 # define SZ 1000
15 L [ i ] = 0;
2 using namespace std ;
16 diff = R - i ;
3 typedef pair < int , int > ii ;
17 if ( diff > 0) L [ i ] = min ( L [ iMirror ] , diff )
4 typedef deque < ii > dii ;
;
5
18
6 double PI = acos ( -1) ;
19 while ( (( i + L [ i ]) < N && ( i - L [ i ]) >
7 double iiabs ( ii a ) { return sqrt ( a . x * a . x + a . y * a . y ) ;}
0) &&
8 ii operator -( ii a , ii b ) { return ii ( a .x - b .x , a .y - b . y
20 ( (( i + L [ i ] + 1) % 2 == 0) ||
) ;}
21 ( text [( i + L [ i ] + 1) /2] == text [( i -
9 double dist ( ii a , ii b ) { return iiabs (a - b ) ;}
L [ i ] - 1) /2] ) ) ) {
10 double ang ( ii a ) { return atan2 ( a .y , a . x ) ;}
22 L [ i ]++;
11 double cot ( double i ) { while (i <= - PI ) i +=2* PI ; while
23 }
(i > PI ) i -=2* PI ; return i ;}
24
12 int ccw ( ii a0 , ii a1 , ii a2 ) {
25 if ( L [ i ] > maxLPSLength ) {
13 int result = ( a2 . x - a1 . x ) *( a0 .y - a1 . y ) - ( a2 .y -
26 maxLPSLength = L [ i ];
a1 . y ) *( a0 .x - a1 . x ) ;
27 maxLPSCenterPosition = i;
14 if ( result < 0) return -1;
28 }
15 if ( result > 0) return 1;
29
16 return 0;
30 if ( i + L [ i ] > R ) {
17 }
31 C = i;
18 double deg ( double i ) { return i *180/ PI ;}
32 R = i + L [ i ];
19 bool intls ( ii l0 , ii l1 , ii s0 , ii s1 ) { return ccw ( l0
33 }
, l1 , s0 ) * ccw ( l0 , l1 , s1 ) !=1;}
34 }
20 bool intss ( ii a0 , ii a1 , ii b0 , ii b1 ) {
35 return maxLPSLength ;
21 if ( ccw ( a0 , a1 , b0 ) >=0&& ccw ( a0 , a1 , b1 ) <=0&& ccw ( b0 ,
36 }
b1 , a0 ) <=0&& ccw ( b0 , b1 , a1 ) >=0) return true ;
22 if ( ccw ( a0 , a1 , b0 ) <=0&& ccw ( a0 , a1 , b1 ) >=0&& ccw ( b0 ,
6.6 Rabin-Karp (AC feb-2015) b1 , a0 ) >=0&& ccw ( b0 , b1 , a1 ) <=0) return true ;
23 return false ;
hashit(t,tsz,len,h): O(tsz) 24 }
25 bool intlp ( ii l0 , ii l1 , ii a ) { return ccw ( l0 , l1 , a )
1. Computes h[i] = hash of t[i..i+len), based on ==0;}
Base. 26 bool intsp ( ii s0 , ii s1 , ii a ) { return dist ( s0 , s1 )
== dist ( s0 , a ) + dist (a , s1 ) ;}
2. To be completely sure of a match. (Only if you really 27 double ccwang ( ii a , ii b , ii c ) { c =c - b ; b =b - a ;
want to do it) Hash twice using different bases and return cot ( ang ( c ) - ang ( b ) ) ;}
28 double insang ( ii a , ii b , ii c ) { return PI - abs (
check both match. ccwang (a ,b , c ) ) ;}
29 double distlp ( ii l0 , ii l1 , ii a ) {
1 large h [ SZ ]; 30 ii d = l1 - l0 ;
2 large hashit ( char * t , int tsz , int len , large * h ) 31 return abs ( d . y * a .x - d . x * a .y - l0 . x * l1 . y + l1 . x * l0 . y )
{ /( double ) iiabs ( d ) ;
3 int i ; large Base =257 , Mod =7778777 , poow =1; 32 }
4 loop (i ,0 , len ) poow = ( Base * poow ) % Mod ; 33 double distsp ( ii s0 , ii s1 , ii a ) {
5 h [0]=0; loop (i ,0 , len ) h [0] = ( Base * h [0] + t [ i ]) 34 if ( insang ( s0 , s1 , a ) <= PI /2 && insang ( s1 , s0 , a ) <= PI
% Mod ; /2) return distlp ( s0 , s1 , a ) ;
6 loop (i ,0 , tsz - len ) h [ i +1] = ( Base * h [ i ] + Mod - 35 return min ( dist (a , s0 ) , dist (a , s1 ) ) ;
poow * t [ i ]% Mod + t [ i + len ]) % Mod ; 36 }
7 return h [0]; 37 bool inpol ( dii & pol , ii a ) {
8 } 38 int polsz =( int ) pol . size () , wn =0 , i ;
9 39 pol . pb ( pol [0]) ;
10 void findp ( char * p , int psz , char * t , int tsz ) { 40 loop (i ,0 , polsz )
11 large key = hashit (p , psz , psz , h ) ; int i ; 41 if ( pol [ i ]. y <= a . y ) { if ( pol [ i +1]. y > a . y && ccw (
12 hashit (a , tsz , psz , h ) ; a , pol [ i ] , pol [ i +1]) ==1) wn ++; }
13 loop (i ,0 , tsz - psz +1) if ( key == h [ i ]) printf ( " Match 42 else if ( pol [ i +1]. y <= a . y && ccw (a , pol [ i ] , pol [ i
at % d .\ n " ,i ) ; +1]) == -1) wn - -;
14 } 43 pol . popb () ;
15 44 return !( wn ==0) ;
16 int main () { // finds b in a 45 }
17 scanf ( " % s " ,a ) ; scanf ( " % s " ,b ) ; 46 // Expected : 4800 6818 1668 5723 8662 3530
18 findp (a , strlen ( b ) ,a , strlen ( a ) ) ; 47 int h , mod =11311 , a =929 , sz =700;
19 return 0; 48 ii p [ SZ ];
20 } 49 dii pol ;
50 int prandom ( int b ) { return h =( a * h + abs ( b ) ) % mod ;}
51 int ftest ( int i , int j ) {
52 if ( j ==0) return intls ( p [ i ] , p [ i +1] , p [ i +2] , p [ i
+3]) ;
53 if ( j ==1) return intss ( p [ i ] , p [ i +1] , p [ i +2] , p [ i

13
+3]) ; 9 ii curr , prev ;
54 if ( j ==2) return distlp ( p [ i ] , p [ i +1] , p [ i +2]) ; 10 stack < ii > S ;
55 if ( j ==3) return distsp ( p [ i ] , p [ i +1] , p [ i +2]) ; 11 FOR (i , 1 , n ) {
56 if ( j ==4) return inpol ( pol , p [ i ]) ; 12 if ( vec [ i ] < vec [0]) {
57 } 13 prev = vec [ i ];
58 int main () { 14 vec [ i ]= vec [0];
59 int i , j ; 15 vec [0]= prev ;
60 h =0; 16 }
61 loop (i ,0 , sz +3) p [ i ]= ii ( prandom (137) , prandom 17 }
(137) ) ; 18 sort ( vec +1 , vec +n , angle_cmp ) ;
62 printf ( " % d \ n " ,h ) ; 19 S . push ( vec [0]) ; // put two starting vertices
63 pol . clear () ; loop (i ,0 , sz /7) pol . pb ( p [ i ]) ; into stack S
64 loop (j ,0 ,5) { 20 S . push ( vec [1]) ;
65 h =0; 21 i = 2; // and start checking the rest
66 loop (i ,0 , sz ) prandom ( i + ftest (i , j ) ) ; 22 while ( i < n ) { // note : N must be >= 3 for
67 printf ( " % d \ n " ,h ) ; this method to work
68 } 23 curr = S . top () ; S . pop () ;
69 return 0; 24 prev = S . top () ; S . push ( curr ) ; // trick to get
70 } the 2 nd item from top of S
25 if ( ccw ( prev , curr , vec [ i ]) >0) { // if these
7.2 Closest Pair Problem 3 points make a left turn
26 S . push ( vec [ i ]) ; // accept
1 ii vec [ LIM ]; 27 i ++;
2 int n ; 28 }
3 29 else S . pop () ; // otherwise pop this point
4 double dist_sq ( ii a , ii b ) { until we have a left turn
5 return (( a .X - b . X ) *( a .X - b . X ) +( a .Y - b . Y ) *( a .Y - b . Y ) 30 }
); 31 cont = S . size () ;
6 } 32 REV (i , S . size () -1 , 0) { // from stack back to
7 vector
8 int main ( void ) { 33 hull [ i ]= S . top () ;
9 int i , j ; 34 S . pop () ;
10 double res ; 35 }
11 setvbuf ( stdin , NULL , _IOFBF , 1 < <18) ; 36 return cont ;
12 setvbuf ( stdout , NULL , _IOFBF , 1 < <18) ; 37 }
13 // READ (" T h e C l o s e s t P a i r P r o b l e m 1 0 2 4 5 . txt ") ; 38
14 while ( scanf ( " % d " , & n ) ==1 && n >0) { 39 // EASIER CONVEX HULL IMPLEME NTATION
15 FOR (i , 0 , n ) scanf ( " % lf % lf " , &( vec [ i ]. X ) , &( 40 // taken from the Stavropol University Notebook
vec [ i ]. Y ) ) ; 41
16 if (n <2) { 42 bool operator <( ii a , ii b ) { return a . x < b . x ||
17 puts ( " INFINITY " ) ; ( a . x == b . x && a . y < b . y ) ; }
18 continue ; 43 // Returns convex hull in counter - clockwise order
19 } .
20 sort ( vec , vec + n ) ; 44 // Note : the last point in the returned list is
21 res =1.0* INF * INF ; the same as the first one .
22 FOR (i , 1 , n ) { 45 vector < ii > ConvexHull ( vector < ii > P ) {
23 REV (j , i -1 , 0) { 46 int n = P . size () , k = 0; vector < ii > H (2* n ) ;
24 if (( vec [ i ]. X - vec [ j ]. X ) *( vec [ i ]. X - vec [ j ]. 47 sort ( P . begin () , P . end () ) ;
X ) >= res ) break ; 48 for ( int i = 0; i < n ; i ++)
25 if ( dist_sq ( vec [ i ] , vec [ j ]) < res ) { 49 { while ( k >= 2 && cross ( H [k -2] , H [k -1] , P [ i
26 res = dist_sq ( vec [ i ] , vec [ j ]) ; ]) <= 0) k - -; H [ k ++] = P [ i ]; }
27 } 50 for ( int i = n -2 , t = k +1; i >= 0; i - -)
28 } 51 { while ( k >= t && cross ( H [k -2] , H [k -1] , P [ i
29 } ]) <= 0) k - -; H [ k ++] = P [ i ]; }
30 res = sqrt ( res ) ; 52 H . resize ( k ) ;
31 if ( res >10000.0) puts ( " INFINITY " ) ; 53 return H ;
32 else printf ( " %.4 lf \ n " , res ) ; 54 }
33 }
34 return 0; 7.4 Formulas
35 }
Triangles:
7.3 Convex-Hull
• Heron’s Formula: Let pa, b, c be the sides of a triangle.
1 ii vec [ LIM ]; Then the area is A = s(s − a)(s − b)(s − c), where
2 ii hull [ LIM ]; the semiperimeter is s = (a + b + c)/2.
3
4 bool angle_cmp ( ii a , ii b ) { return ccw ( vec [0] , a , • The inscribed circle has radius r = A/s and it’s center
b ) >0;} is the meeting point between the angle bisectors.
5 bool same ( double a , double b ) { return ( fabs (a - b )
<=1 e -9) ;}
6
• The circumscribed circle has radius R = abc/(4A),
7 int GrahamScan ( int n ) { and it’s center is the meeting between the perpendic-
8 int cont , i ; ular bisectors.

14
Spheres: (Organize) 8 Mathematics.
• Great circle distance: (CompetitiveProg) 8.1 GCD
1 double gcDistance ( double pLat , double pLong ,
double qLat , double qLong , double radius ) 1 // Iterative GCD in C ++
{ 2 typedef int tipo ; // can also be long long
2 pLat *= PI / 180; pLong *= PI / 180; // 3 tipo GCD ( tipo a , tipo b ) {
conversion from degree to radian 4 tipo x ;
3 qLat *= PI / 180; qLong *= PI / 180; 5 while (b >0) { x = a ; a = b ; b = x % a ; }
4 return radius * acos ( 6 return a ;
5 cos ( pLat ) * cos ( pLong ) * cos ( qLat ) * cos ( qLong ) 7 }
+
6 cos ( pLat ) * sin ( pLong ) * cos ( qLat ) * sin ( qLong ) 8.2 Extended Euclid
+
7 sin ( pLat ) * sin ( qLat ) ) ; 1 void e xtended Euclid ( int a , int b ) {
2 if ( b == 0) { x = 1; y = 0; d = a ; return ; }
3 exten dedEucl id (b , a % b ) ;
• From chord length(wikipedia): Let φ1 ,λ1 and φ2 ,λ2
4 int x1 = y , y1 = x - ( a / b ) * y ;
be the geographical latitude and longitude of two 5 x = x1 ; y = y1 ;
points 1 and 2, and ∆φ,∆λ their absolute differences. 6 }
A line through three-dimensional space between 8.3 Cycle Finding
points of interest on a spherical Earth is the chord
of the great circle between the points. The central Turtle and hare implementation.
angle between the two points can be determined from 1 typedef pair < large , large > ll ;
the chord length. The great circle distance is propor- 2 large fv [ SZ ];
tional to the central angle. 3
4 ll cycle () {
The great circle chord length, Ch , may be calculated 5 large H ,T , fH , fT , L =0;
as follows for the corresponding unit sphere, by means 6 for ( H =2 , T =1 , fH = f ( f ( L ) ) , fT = f ( L ) ; fH != fT ;) {
7 H +=2; T ++; fH = f ( f ( fH ) ) ; fT = f ( fT ) ;
of Cartesian subtraction: 8 }
9 for ( H =0 , fH = L ; fH != fT ;) {
10 H ++; T ++; fH = f ( fH ) ; fT = f ( fT ) ;
11 }
∆X = cos φ2 cos λ2 − cos φ1 cos λ1 ; (1) 12 for ( T = H +1 , fT = f ( fH ) ; fH != fT ;) { T ++; fT = f ( fT ) ;}
∆Y = cos φ2 sin λ2 − cos φ1 sin λ1 ; (2) 13 return ll (T ,T - H ) ; // ( phase ( mu ) , period ( lamda )
)
∆Z = sin φ2 − sin φ1 ; (3) 14 }
p
C = (∆X)2 + (∆Y )2 + (∆Z)2 (4)
8.4 Sieve of Erathostenes
The central angle is:
∆σ = 2 arcsin C2 .

1 int notp [ SZ ];
2 vector < int > primes ;
The great circle distance is: 3 large Bound ;
4
d = r∆σ. 5 void sieve ( int bound ) {
6 large i , j ;
7 Bound = bound +1;
8 memset ( notp ,0 , sizeof ( notp ) ) ;
9 notp [0]= notp [1]=1;
10 for ( i =2; i <= Bound ; i ++) if (! notp [ i ]) {
11 for ( j = i * i ; j <= Bound ; j += i ) notp [ j ]=1;
12 primes . push_back (( int ) i ) ;
13 }
14 }
15
16 large sumPF ( large N ) {
17 large idx =0 , PF = primes [ idx ] , ans =0;
18 while ( N !=1 && PF * PF <= N ) {
19 while ( N % PF ==0) N /= PF , ans += PF ;
20 PF = primes [++ idx ];
21 }
22 return N ==1? ans : ans + N ;
23 }

8.5 Pollard-Rho
EMPTY

15
8.6 Totient function 27 int polymult ( int * a , int * b , int * c , int asz , int
bsz ) {
EMPTY 28 int csz = pow (2 , ceil ( log ( asz + bsz ) / log (2) ) ) ;
29 int i ;
1 phi ( n ) := |{ m <= n : gcd (m , n ) ==1}| 30 memset ( ima ,0 , csz *16) ; // im uses 16 bytes
2 31 memset ( imb ,0 , csz *16) ;
3 Eulers product forumla : 32 loop (i ,0 , asz ) ima [ i ] = a [ i ];
4 phi ( n ) = n * product (1 -1/ p : p is prime and 33 loop (i ,0 , bsz ) imb [ i ] = b [ i ];
divides n ) 34 fft ( ima ,u ,v , csz ) ;
5 Divisor sum : 35 fft ( imb ,u ,v , csz ) ;
6 sum ( phi ( d ) : d divides n ) = n 36 loop (i ,0 , csz ) imc [ i ] = ima [ i ]* imb [ i ];
37 ifft ( imc ,u ,v , csz ) ;
38 loop (i ,0 , csz ) c [ i ] = ( int ) round ( real ( imc [ i ]) ) ;
8.7 FFT (AC feb-2015) 39 return csz ;
40 }
fft(p,u,v,n): O(nlogn)

1. Computes the Fast Fourier Transform, fft, of p[0..n)


in-situ. 8.8 Primes.
2. Arrays u and v are just n-sized auxiliary arrays. Easy to remember primes: (Wikipedia and Stack Over-
flow)
3. Integer n must be a power of two.
1 101 , 131 , 151 , 181 , 191 , 313 , 353 , 373 , 383 ,
ifft(p,u,v,n): O(nlogn) 2 727 , 757 , 787 , 797 , 919 , 929 , 11311 , 11411 ,
3 33533 , 77377 , 77477 , 77977 , 1114111 , 1117111 ,
1. Computes the inverse fft of p[0..n) in-situ. 4 3331333 , 3337333 , 7772777 , 7774777 , 7778777 ,
5 111181111 , 111191111 , 777767777 , 77777677777 ,
6 99999199999.
2. Arrays u and v are just n-sized auxiliary arrays.
Prime list under 1000 (0-indexed):
3. Integer n must be a power of two.
-2 0 1 2 3 4 5 6 7 8 9
polymult(a,b,c,asz,bsz): O(nlogn) -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0 2 3 5 7 11 13 17 19 23 29
1. P
Computes the product
Pi<bsz between polynomials 1 31 37 41 43 47 53 59 61 67 71
i<asz
i=0 a[i]xi and i=0 b[i]x
b
in the c polyno- 2 73 79 83 89 97 101 103 107 109 113
mial. 3 127 131 137 139 149 151 157 163 167 173
4 179 181 191 193 197 199 211 223 227 229
5 233 239 241 251 257 263 269 271 277 281
2. Returns the size of c. 6 283 293 307 311 313 317 331 337 347 349
7 353 359 367 373 379 383 389 397 401 409
3. c capacity must satisfy csz ≥ 2n > asz +bsz for some 8 419 421 431 433 439 443 449 457 461 463
n ∈ Z +. 9 467 479 487 491 499 503 509 521 523 541
10 547 557 563 569 571 577 587 593 599 601
11 607 613 617 619 631 641 643 647 653 659
1 # define SZ 1000005
12 661 673 677 683 691 701 709 719 727 733
2
13 739 743 751 757 761 769 773 787 797 809
3 using namespace std ;
14 811 821 823 827 829 839 853 857 859 863
4 typedef complex < double > im ;
15 877 881 883 887 907 911 919 929 937 941
5
16 947 953 967 971 977 983 991 997
6 double PI = acos ( -1) ;
7
8 im p [ SZ ] , u [ SZ ] , v [ SZ ] , ima [ SZ ] , imb [ SZ ] , imc [ SZ ]; Last prime below 10n is 10n − val
9
10 void fft ( im * p , im * u , im * v , int n ) { -2 0 1 2 3 4 5 6 7 8 9
11 if ( n ==1) return ; -1 --------------------------------------
12 int i ; im w =1 , wn = exp (( im ) ( -2 j * PI / n ) ) ; 0 - 3 3 3 7 9 17 9 11 63
13 n = n /2; 1 33 23 11 29 27 11 63 3 11
14 loop (i ,0 , n ) u [ i ]= p [2* i ] , v [ i ]= p [2* i +1];
15 fft (u , u +n , v +n , n ) ; How many primes up to 10n ?
16 fft (v , u +n , v +n , n ) ;
17 loop (i ,0 ,2* n ) { p [ i ]=( u [ i % n ]+ w * v [ i % n ]) ; w = w * wn ; -2 1 | 4
} -1 2 | 25
18 } 0 3 | 168
19 1 4 | 1229
20 void ifft ( im * p , im * u , im * v , int n ) { 2 5 | 9592
21 int i ; 3 6 | 78498
22 loop (i ,0 , n ) p [ i ]= conj ( p [ i ]) ; 4 7 | 664579
23 fft (p ,u ,v , n ) ; 5 8 | 5761455
24 loop (i ,0 , n ) p [ i ]= conj ( p [ i ]) /( im ) n ; 6 9 | 50847534
25 } 7 10 | 455052511
26

16
8.9 Combinatorics. Partitions of {1,..,m} of length n. A partition P
m
 of a set A is a set of non-empty disjoint sets of A with
Binomial coefficients. There are n subsets of
A = ∩Pi ∈P Pi .
{1, .., m} of size n.
There are S(m, n) partitions of size n of {1, .., m}.
1. m m−1 m−1
 m
; 0 = m
  
n = n−1 + n m =1 1. S(m, n) = n S(m − 1, n) + S(m − 1, n − 1)
2. m m
 
n = m−n 2. S(10, 1..10) = [1, 511, 9330, 34105, 42525, 22827, 5880, 750, 45, 1]
3. m m!

n = n!(m−n)! B(10) = 115975
4. There are m+n

n strings with m zeros and n ones. Pm−1
3. B(m) = i=0 m−1

B(i); B(0) = 1
i
5. There are m+1

n strings with m zeros and n no- Catalan numbers. There are C(n) binary strings
adjacent ones. A[0..2n) with n ones, n zeros and such that A[0..i) doesn’t
Multisets. There are m

multisets of {1, .., m} of have more ones than zeros for each i ∈ [0..2n).
n
size n. 2(2n+1)
1. C0 = 1 y Cn+1 = n+2 Cn ,
1. m := m+n−1
 
n n 2. C[0..10) = 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862.
  C[10..15) = 16796, 58786, 208012, 742900, 2674440.
2. m m−1 m
; m 0
   
n = n + n−1 0 = 0 =
C[24] = 1289904147324.
0

1, n = 0 n
1 2n
 (2n)! Q n+k
  n+1  3. Cn = n+1 n = (n+1)! n! = k para n ≥ 0.
3. m n = m−1 k=2
Pn
Derangements. There are !m auto-bijections of 4. C0 = 1 y Cn+1 = i=0 Ci Cn−i para n ≥ 0;
{1, .., m} without fixed points. Pisano Period. T (n) is the period of the sequence
1. !m := (m − 1)(!(m − 1)+!(m − 2)); !0 = 1, !1 = 0 (fib(i)%n), where (fib(i)) is the Fibonnacci sequence.
Pm
2. !m = m! − i=1 mi !(m − i)
 1. T (10[0..) ) = 1, 60, 300, 1500, 15000, ..., 15 · 10n−1

Pm (−1)i 2. T (2[0..5) ) = 1, 3, 6, 12, 24


3. !m = m! i=0 i! T (2[5..10) ) = 48, 96, 192, 384, 768
4. ![0 . . . 7) = [1, 0, 1, 2, 9, 44, 265] !13 = 2290792932 T (2[10..15) ) = 1536, 3072, 6144, 12288, 24576
T (2[15..20) ) = 49152, 98304, 196608, 393216, 786432
Partial derangements. There are D(m, n) auto- T (2[20..21) ) = 1572864
bijections of {1, .., m} with n fixed points.
Powers of two.
1. D(m, n) := m

n D(m, 0)
1. 2[0..5) = 1, 2, 4, 8, 16
2. D(m, 0) =!m 2[5..10) = 32, 64, 128, 256, 512
2[10..15) = 1024, 2048, 4096, 8192, 16384
3. D(7, 0 . . . 7) = 7, 1854, 1855, 924, 315, 70, 21, 0, 1
2[15..20) = 32768, 65536, 131072, 262144, 524288
2[20..21) = 1048576
Partitions of m of length n. A partition A ⊆ Z+
of a positive integer m is an ordered multiset with m =
P
ai ∈A ai .
There are P (m, n) partitions of m of length n.
1. P (m, n) := |{p ∈ P(m) : |p| = n}| = |{p ∈ P(m) :
max(pi ∈ p) = n}|
Pn
2. P (m, n) = i=1 P (m − n, i)
3. P (m, n) = P (m − 1, n − 1) + P (m − n, n); P (m, 1) =
1 = P (0, 0)
4. P (30, 1 . . . 10) = [1, 15, 75, 206, 377, 532, 618, 638, 598, 530]
P (30) = 3590
Pn
5. There are P (m − 1 ci + n, n) partitions of m in n
summands xi ≥ ci .

17
9 Solution not working?
1. If available: Print it! and swap places with a partner.

2. Check you are reading from standard input (not


freopen).
3. Check lld instead of d if scanning/printing large.
4. Check header issues.

5. Check size issues.


6. Check you’re cleaning between test cases.
7. Check your output matches exactly the expected.

8. Search hidden tips in problem text.


9. Test simple but tricky test cases if they exist.
10. Do another problem.

10 Bibliography
1. Wikipedia.
2. Combinatorial algorithms, de Kreher y Stinson.
3. (1) Competitve Programming 1, 2, y 3 de Steven y
Felix Halim.
4. Stanford University ACM Team Notebook (2013-14)
http://stanford.edu/~liszt90/acm/notebook.
html

5. (4) http://geomalgorithms.com/a03-_
inclusion.html

18

You might also like