ECIGMA - Notebook (C++) Codes For ACM ICPC
ECIGMA - Notebook (C++) Codes For ACM ICPC
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
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 }
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 }
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 }
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)
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
17
9 Solution not working?
1. If available: Print it! and swap places with a partner.
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