Standard Code Library Hao Yuan Department of Computer Science and Engineering Shanghai Jiaotong University October 23, 2003 Contents 1 Algorithms and Datastructures 1.1 High Precision in C . . . . . . . . . . 1.2 High Precision in C Plus Plus . . . . . 1.3 High Precision Floating-point Number 1.4 Fraction Class . . . . . . . . . . . . . . 1.5 Binary Heap . . . . . . . . . . . . . . 1.6 Winner Tree . . . . . . . . . . . . . . . 1.7 Digital Tree . . . . . . . . . . . . . . . 1.8 Segment Tree . . . . . . . . . . . . . . 1.9 Segment Tree in IOI’2001 . . . . . . . 1.10 Union-Find Set . . . . . . . . . . . . . 1.11 Quick Sort . . . . . . . . . . . . . . . . 1.12 Merge Sort . . . . . . . . . . . . . . . 1.13 Radix Sort . . . . . . . . . . . . . . . 1.14 Select K th Smallest Element . . . . . 1.15 KMP . . . . . . . . . . . . . . . . . . . 1.16 Suffix Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 4 6 8 8 9 10 10 11 11 11 12 12 12 12 13 2 Graph Theory and Network Algorithms 2.1 SSSP — Dijkstra + Binary Heap . . . . . . . 2.2 SSSP — Bellman Ford + Queue . . . . . . . 2.3 MST — Kruskal . . . . . . . . . . . . . . . . 2.4 Minimum Directed Spanning Tree . . . . . . 2.5 Maximum Matching on Bipartite Graph . . . 2.6 Maximum Cost Perfect Matching on Bipartite 2.7 Maximum Matching on General Graph . . . . 2.8 Maximum Flow — Ford Fulkson in Matrix . 2.9 Maximum Flow — Ford Fulkson in Link . . . 2.10 Minimum Cost Maximum Flow in Matrix . . 2.11 Minimum Cost Maximum Flow in Link . . . 2.12 Recognizing Chordal Graph . . . . . . . . . . 2.13 DFS — Bridge . . . . . . . . . . . . . . . . . 2.14 DFS — Cutvertex . . . . . . . . . . . . . . . 2.15 DFS — Block . . . . . . . . . . . . . . . . . . 2.16 DFS — Topological Sort . . . . . . . . . . . . 2.17 Strongly Connected Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 14 15 15 16 16 17 17 18 19 20 21 21 22 22 23 24 24 3 Number Theory 3.1 Greatest Common Divisor . . 3.2 Chinese Remainder Theorem 3.3 Prime Generator . . . . . . . 3.4 φ Generator . . . . . . . . . . 3.5 Discrete Logarithm . . . . . . 3.6 Square Roots in Zp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 25 25 26 26 27 28 4 Algebraic Algorithms 4.1 Linear Equations in Z2 4.2 Linear Equations in Z 4.3 Linear Equations in Q 4.4 Linear Equations in R 4.5 Roots of Polynomial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 29 30 30 31 31 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 . . . . . . . . . . . . . . . . 4.6 4.7 4.8 4.9 4.10 4.11 Roots of Cubic and Quartic . . . . . . Fast Fourier Transform . . . . . . . . . FFT - Polynomial Multiplication . . . FFT - Convolution . . . . . . . . . . . FFT - Reverse Bits . . . . . . . . . . . Linear Programming - Primal Simplex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 33 34 34 34 36 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 38 39 41 43 44 44 46 47 48 49 50 52 54 55 6 Classic Problems 6.1 Bernoulli Number Generator . . . . . 6.2 Baltic OI’99 Expressions . . . . . . . . 6.3 Bead Coloring — Pólya Theory . . . . 6.4 Binary Stirling Number . . . . . . . . 6.5 Box Surface Distance . . . . . . . . . . 6.6 Calculate Expression . . . . . . . . . . 6.7 Cartesian Tree . . . . . . . . . . . . . 6.8 Catalan Number Generator . . . . . . 6.9 Coloring Regular Polygon . . . . . . . 6.10 Counting Inverse Pairs . . . . . . . . . 6.11 Counting Trees . . . . . . . . . . . . . 6.12 Eight Puzzle Problem . . . . . . . . . 6.13 Extended Honai Tower . . . . . . . . . 6.14 High Precision Square Root . . . . . . 6.15 Largest Empty Rectangle . . . . . . . 6.16 Last Non-Zero Digit of N! . . . . . . . 6.17 Least Common Ancestor . . . . . . . . 6.18 Longest Common Substring . . . . . . 6.19 Longest Non Descending Sub Sequence 6.20 Join and Disjoin . . . . . . . . . . . . 6.21 Magic Square . . . . . . . . . . . . . . 6.22 Optimal Binary Search Tree . . . . . . 6.23 Pack Rectangles — Cut Rectangles . . 6.24 Pack Rectangles — O(N 2 ) . . . . . . . 6.25 Parliament . . . . . . . . . . . . . . . 6.26 π Generator . . . . . . . . . . . . . . . 6.27 Plant Trees — Iteration . . . . . . . . 6.28 Plant Trees — Segment Tree . . . . . 6.29 Range Maximum Query . . . . . . . . 6.30 Travelling Salesman Problem . . . . . 6.31 Tree Heights . . . . . . . . . . . . . . 6.32 Minimum Cyclic Presentation . . . . . 6.33 Maximum Clique . . . . . . . . . . . . 6.34 Maximal Non-Forbidden Submatrix . . 6.35 Maximum Two Chain Problem . . . . 6.36 N Queens Problem . . . . . . . . . . . 6.37 de Bruijn Sequence Generator . . . . . 6.38 ZOJ 1482 Partition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 57 58 58 59 59 59 60 61 62 62 63 63 66 66 67 69 69 71 73 73 74 75 75 76 76 76 77 77 78 79 80 81 82 83 83 85 85 86 5 Computational Geometry 5.1 Basic Operations . . . . . . . . 5.2 Extended Operations . . . . . 5.3 Convex Hull . . . . . . . . . . . 5.4 Point Set Diameter . . . . . . . 5.5 Closest Pair . . . . . . . . . . . 5.6 Circles . . . . . . . . . . . . . . 5.7 Largest Empty Convex Polygon 5.8 Triangle Centers . . . . . . . . 5.9 Polyhedron Volume . . . . . . . 5.10 Planar Graph Contour . . . . . 5.11 Rectangles Area . . . . . . . . 5.12 Rectangles Perimeter . . . . . . 5.13 Smallest Enclosing Circle . . . 5.14 Smallest Enclosing Ball . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 while ( c . s [ i ] ) { c . s [ i +1]=c . s [ i ] / 1 0 ; c . s [ i ]%=10; i ++; } while ( i >1 && ! c . s [ i ] ) i −−; c . l e n=i ; return c ; } HP HP : : operator+(const HP &b ) { int i ; HP c ; c . s [ 1 ] = 0 ; fo r ( i = 1 ; i<=l e n | | i<=b . l e n | | c . s [ i ] ; i ++) { i f ( i<=l e n ) c . s [ i ]+=s [ i ] ; i f ( i<=b . l e n ) c . s [ i ]+=b . s [ i ] ; c . s [ i +1]=c . s [ i ] / 1 0 ; c . s [ i ]%=10; } c . l e n=i − 1 ; i f ( c . l e n ==0 ) c . l e n =1; return c ; } HP HP : : operator −(const HP &b ) { int i , j ; HP c ; fo r ( i =1, j = 0 ; i<=l e n ; i ++) { c . s [ i ]= s [ i ]− j ; i f ( i<=b . l e n ) c . s [ i ]−=b . s [ i ] ; i f ( c . s [ i ] < 0 ) { j = 1 ; c . s [ i ] + = 1 0 ; } e l s e j =0; } c . l e n=l e n ; while ( c . l e n >1 && ! c . s [ c . l e n ] ) c . l e n −−; return c ; } int HP : : Compare ( const HP &y ) { i f ( l e n >y . l e n ) return 1 ; i f ( l e n <y . l e n ) return −1; int i=l e n ; while ( ( i >1)&&( s [ i ]==y . s [ i ] ) ) i −−; return s [ i ]−y . s [ i ] ; } HP HP : : operator / ( const HP &b ) { int i , j ; HP d ( 0 ) , c ; fo r ( i=l e n ; i >0; i −−) { i f ( ! ( d . l e n ==1 && d . s [ 1 ] = = 0 ) ) { f or ( j=d . l e n ; j >0; j −−) d . s [ j +1]=d . s [ j ]; ++ d . l e n ; } d . s [1]= s [ i ] ; c . s [ i ]=0; while ( ( j=d . Compare ( b)) >=0 ) { d=d−b ; c . s [ i ]++; i f ( j ==0) break ; } } c . l e n=l e n ; while ( ( c . l e n >1)&&(c . s [ c . l e n ]==0)) c . l e n −−; return c ; } HP HP : : operator%(const HP &b ) { int i , j ; HP d ( 0 ) ; fo r ( i=l e n ; i >0; i −−) { i f ( ! ( d . l e n ==1 && d . s [ 1 ] = = 0 ) ) { f or ( j=d . l e n ; j >0; j −−) d . s [ j +1]=d . s [ j ]; ++ d . l e n ; } d . s [1]= s [ i ] ; while ( ( j=d . Compare ( b )) >=0 ){ d=d−b ; i f ( j ==0) break ; } } return d ; } 5 Chapter 1 Algorithms and Datastructures 1.1 High Precision in C #define maxlen 1 0 0 0 struct HP { int l e n , s [ maxlen ] ; } ; void PrintHP (HP x ) { for ( int i=x . l e n ; i >=1; i −−) cout<<x . s [ i ] ; } void Str2HP ( const char ∗ s ,HP &x ) { x . l e n=s t r l e n ( s ) ; fo r ( int i =1; i<=x . l e n ; i ++) x . s [ i ]= s [ x . l e n −i ]− ’ 0 ’ ; } void Int2HP ( int i n t e ,HP &x ) { i f ( i n t e ==0) { x . l e n = 1 ; x . s [ 1 ] = 0 ; return ; } ; fo r ( x . l e n =0; i n t e > 0 ; ) { x . s[++x . l e n ]= i n t e %10; i n t e / = 1 0 ; } ; } void Multi ( const HP a , const HP b ,HP & c ) { int i , j ; c . l e n=a . l e n+b . l e n ; fo r ( i =1; i<=c . l e n ; i ++) c . s [ i ] = 0 ; fo r ( i =1; i<=a . l e n ; i ++) for ( j =1; j<=b . l e n ; j ++) c . s [ i+j −1]+=a . s [ i ] ∗ b . s [ j ] ; fo r ( i =1; i <c . l e n ; i ++) { c . s [ i +1]+=c . s [ i ] / 1 0 ; c . s [ i ]%=10; } while ( c . s [ i ] ) { c . s [ i +1]=c . s [ i ] / 1 0 ; c . s [ i ]%=10; i ++; } while ( i >1 && ! c . s [ i ] ) i −−; c . l e n=i ; } void Plus ( const HP a , const HP b ,HP & c ) { int i ; c . s [ 1 ] = 0 ; fo r ( i = 1 ; i<=a . l e n | | i<=b . l e n | | c . s [ i ] ; i ++) { i f ( i<=a . l e n ) c . s [ i ]+=a . s [ i ] ; i f ( i<=b . l e n ) c . s [ i ]+=b . s [ i ] ; c . s [ i +1]=c . s [ i ] / 1 0 ; c . s [ i ]%=10; } c . l e n=i − 1 ; i f ( c . l e n ==0 ) c . l e n =1; } void S u b t r a c t ( const HP a , const HP b ,HP & c ) { fo r ( int i =1, j = 0 ; i<=a . l e n ; i ++) { c . s [ i ]=a . s [ i ]− j ; i f ( i<=b . l e n ) c . s [ i ]−=b . s [ i ] ; i f ( c . s [ i ] < 0 ) { j = 1 ; c . s [ i ] + = 1 0 ; } e l s e j =0; } 3 c . l e n=a . l e n ; while ( c . l e n >1 && ! c . s [ c . l e n ] ) c . l e n −−; } int HPCompare ( const HP x , const HP y ) { i f ( x . l e n >y . l e n ) return 1 ; i f ( x . l e n <y . l e n ) return −1; int i=x . l e n ; while ( ( i >1)&&(x . s [ i ]==y . s [ i ] ) ) i −−; return x . s [ i ]−y . s [ i ] ; } void D i v i d e ( const HP a , const HP b , HP &c ,HP &d ) { int i , j ; d . l e n = 1 ; d . s [ 1 ] = 0 ; fo r ( i=a . l e n ; i >0; i −−) { i f ( ! ( d . l e n ==1 && d . s [ 1 ] = = 0 ) ) { f or ( j=d . l e n ; j >0; j −−) d . s [ j +1]=d . s [ j ]; ++ d . l e n ; } d . s [1]= a . s [ i ] ; c . s [ i ]=0; while ( ( j=HPCompare ( d , b)) >=0 ) { S u b t r a c t ( d , b , d ) ; c . s [ i ]++; i f ( j ==0) break ; } } c . l e n=a . l e n ; while ( ( c . l e n >1)&&(c . s [ c . l e n ]==0)) c . l e n −−; } 1.2 High Precision in C Plus Plus const int maxlen = 1 0 0 0 0 ; c l a s s HP { public : int l e n , s [ maxlen ] ; HP( ) { ( ∗ t h i s ) = 0 ; } ; HP( int i n t e ) { ( ∗ t h i s )= i n t e ; } ; HP( const char∗ s t r ) { ( ∗ t h i s )= s t r ; } ; friend ostream & operator<<(ostream & cout , const HP &x ) ; HP operator=( int i n t e ) ; HP operator=(const char∗ s t r ) ; HP operator ∗ ( const HP &b ) ; HP operator+(const HP &b ) ; HP operator −(const HP &b ) ; HP operator / ( const HP &b ) ; HP operator%(const HP &b ) ; int Compare ( const HP &b ) ; }; ostream & operator<<(ostream & cout , const HP &x ) { for ( int i=x . l e n ; i >=1; i −−) cout<<x . s [ i ] ; return c o u t ; } HP HP : : operator=(const char ∗ s t r ) { l e n=s t r l e n ( s t r ) ; fo r ( int i =1; i<=l e n ; i ++) s [ i ]= s t r [ l e n −i ]− ’ 0 ’ ; return ∗ t h i s ; } HP HP : : operator=( int i n t e ) { i f ( i n t e ==0) { l e n = 1 ; s [ 1 ] = 0 ; return ( ∗ t h i s ) ; } ; fo r ( l e n =0; i n t e > 0 ; ) { s[++ l e n ]= i n t e %10; i n t e / = 1 0 ; } ; return ( ∗ t h i s ) ; } HP HP : : operator ∗ ( const HP &b ) { int i , j ; HP c ; c . l e n=l e n+b . l e n ; fo r ( i =1; i<=c . l e n ; i ++) c . s [ i ] = 0 ; fo r ( i =1; i<=l e n ; i ++) for ( j =1; j<=b . l e n ; j ++) c . s [ i+j −1]+=s [ i ] ∗ b . s [ j ] ; fo r ( i =1; i <c . l e n ; i ++) { c . s [ i +1]+=c . s [ i ] / 1 0 ; c . s [ i ]%=10; } 4 1.3 High Precision Floating-point Number const int f p r e c = 1 0 0 ; // f l o a t i n g −p o i n t p r e c i s i o n HP z e r o =0; c l a s s FS{ public : FS ( ) ; void S e t Z e r o ( ) ; FS ( int i n t e ) { ( ∗ t h i s )= i n t e ; } FS ( char ∗ s ) { ( ∗ t h i s )= s ; } FS operator=(char ∗ s ) ; FS operator=( int i n t e ) ; FS operator+(FS b ) ; FS operator −(FS b ) ; FS operator ∗ ( FS b ) ; FS operator / (FS b ) ; friend ostream & operator<<(ostream & cout , FS x ) ; int s i g n , p r e c ; HP num ; }; void FS : : S e t Z e r o ( ) { s i g n = 1 ; num= 0 ; p r e c = 0 ; } FS : : FS ( ) { S e t Z e r o ( ) ; } ostream & operator<<(ostream & cout , FS x ) { i f ( x . s i g n <0) cout<<”−” ; int i , k , low =1; fo r ( i=x . num . l e n ; i >x . p r e c ; i −−) cout<<x . num . s [ i ] ; i f ( x . num . l e n<=x . p r e c ) cout<<”0” ; i f ( x . num . Compare ( z e r o ) = = 0 ) { cout<<” . 0 ” ; return c o u t ; } k=i ; while ( k>0 && x . num . s [ k ] = = 0 ) k−−; i f ( k ==0) { cout<<” . 0 ” ; return c o u t ; } cout<<” . ” ; i f ( x . num . l e n <x . p r e c ) for ( int j =0; j <x . prec−x . num . l e n ; j ++) cout<<” 0 ” ; while ( x . num . s [ low ]==0) low++; while ( i>=low ) cout<<x . num . s [ i −−]; return c o u t ; } FS FS : : operator=( int i n t e ) { prec = 0; i f ( i n t e >=0 ) { s i g n = 1 ; num = i n t e ; } else { s i g n = −1; num = − i n t e ; } return ( ∗ t h i s ) ; } FS FS : : operator=(char ∗ s ) { int p , i , j , l ; SetZero ( ) ; i f ( s [0]== ’− ’ ) { s i g n = −1; s ++; }; i f ( s [0]== ’+ ’ ) { s i g n = 1 ; s ++; }; l = strlen (s ); fo r ( p = 0 ; p<l ; p++) i f ( s [ p]== ’ . ’ ) break ; i f ( p==l ) p r e c = 0 ; e l s e p r e c = l −1−p ; fo r ( i=l −1, j = 0 ; i >=0; i −−) i f ( s [ i ] ! = ’ . ’ ) num . s[++ j ] = s [ i ]− ’ 0 ’ ; while ( j >1 && num . s [ j ]==0) −− j ; num . l e n = j ; return ( ∗ t h i s ) ; } 6 void L S h i f t ( FS &a , int s l ) { a . p r e c+=s l ; a . num . l e n+=s l ; int i ; fo r ( i=a . num . l e n ; i >s l ; i −−) a . num . s [ i ]=a . num . s [ i −s l ] ; while ( i >0) a . num . s [ i −−]=0; } void R S h i f t ( FS &a , int s l ) { a . prec−=s l ; a . num . l e n−=s l ; int i ; fo r ( i = 1 ; i<=a . num . l e n ; i ++) a . num . s [ i ]=a . num . s [ i+s l ] ; } FS FS : : operator+(FS b ) { FS c ; i f ( prec>b . p r e c ) L S h i f t ( b , prec−b . p r e c ) ; e l s e i f ( prec<b . p r e c ) L S h i f t ( ( ∗ t h i s ) , b . prec−p r e c ) ; i f ( s i g n==b . s i g n ) { c . s i g n=s i g n ; c . p r e c=p r e c ; c . num=num+b . num ; i f ( c . num . Compare ( z e r o )==0 ) c . S e t Z e r o ( ) ; } else { c . p r e c=p r e c ; i f ( num . Compare ( b . num)==0) c . S e t Z e r o ( ) ; e l s e i f ( num . Compare ( b . num) > 0 ) { c . s i g n=s i g n ; c . num=num−b . num ; } e l s e i f ( num . Compare ( b . num) < 0 ) { c . s i g n=b . s i g n ; c . num=b . num−num ; } i f ( c . num . Compare ( z e r o )==0 ) c . S e t Z e r o ( ) ; } i f ( c . prec > fprec ) RShift ( c , c . prec − fprec ) ; return c ; } FS FS : : operator −(FS b ) { b . sign = − b . sign ; FS c = ( ∗ t h i s ) + b ; b . sign = − b . sign ; return c ; } FS FS : : operator ∗ ( FS b ) { FS c ; c . sign = sign ∗ b . sign ; c . prec = prec + b . prec ; c . num = num ∗ b . num ; i f ( c . num . Compare ( z e r o )==0 ) c . S e t Z e r o ( ) ; i f ( c . prec > fprec ) RShift ( c , c . prec − fprec ) ; return c ; } FS FS : : operator / (FS b ) // 355/133 = 3.1415929203539823008849557522124 { FS c , d ; // c = d / b d = (∗ this ) ; LShift (d , f p r e c ) ; c . sign = d . sign ∗ b . sign ; c . prec = d . prec ; LShift (d , b . prec ) ; c . num = d . num / b . num ; i f ( c . prec > fprec ) RShift ( c , c . prec − fprec ) ; return c ; } 7 1.4 Fraction Class int gcd ( int a , int b ) { i f ( b==0) return a ; return gcd ( b , a%b ) ; } int lcm ( int a , int b ) { return a/ gcd ( a , b ) ∗ b ; } c l a s s F r a c t i o n { public : int a , b ; // ( a/ b = numerator / denominator ) int s i g n ( int x ) { return ( x >0?1: −1 ); } Fraction ( ) : a (0) , b(1){} F r a c t i o n ( int x ) : a ( x ) , b ( 1 ) { } F r a c t i o n ( int x , int y ) { int m = gcd ( abs ( x ) , abs ( y ) ) ; a = x/m ∗ s i g n ( y ) ; i f ( a==0) b = 1 ; e l s e b = abs ( y/m ) ; } int g e t d e n o m i n a t o r ( ) { return b ; } int g e t n u m e r a t o r ( ) { return a ; } F r a c t i o n operator+(const F r a c t i o n & f ) { int m = gcd ( b , f . b ) ; return F r a c t i o n ( f . b/m ∗ a + b/m ∗ f . a , b/m ∗ f . b ) ; } F r a c t i o n operator −(const F r a c t i o n & f ) { int m = gcd ( b , f . b ) ; return F r a c t i o n ( f . b/m ∗ a − b/m ∗ f . a , b/m ∗ f . b ) ; } F r a c t i o n operator ∗ ( const F r a c t i o n & f ) { int m1 = gcd ( abs ( a ) , f . b ) ; int m2 = gcd ( b , abs ( f . a ) ) ; return F r a c t i o n ( ( a/m1) ∗ ( f . a/m2 ) , ( b/m2) ∗ ( f . b/m1 ) ) ; } F r a c t i o n operator / ( const F r a c t i o n & f ) { return ( ∗ t h i s ) ∗ F r a c t i o n ( f . b , f . a ) ; } friend ostream &operator<<(ostream & out , const F r a c t i o n & f ) { i f ( f . a==0) c o u t < < 0; e l s e i f ( f . b==1) c o u t << f . a ; e l s e c o u t << f . a << ’ / ’ << f . b ; return out ; } }; 1.5 Binary Heap #define MAXN 1 0 4 8 5 7 6 int n , HeapSize , Heap [MAXN+ 1 ] ; void HeapUp ( int p ) { int q=p>>1,a=Heap [ p ] ; while ( q ) { i f ( a<Heap [ q ] ) Heap [ p]=Heap [ q ] ; e l s e break ; p=q ; q=p > > 1; } Heap [ p]=a ; } void AddToHeap ( int a ) { Heap[++HeapSize ]=a ; HeapUp ( HeapSize ) ; } 8 void HeapDown ( int p ) { int q=p<<1,a=Heap [ p ] ; while ( q <= HeapSize ) { i f ( q<HeapSize && Heap [ q+1]<Heap [ q ] ) q++; i f ( Heap [ q ] < a ) Heap [ p ] = Heap [ q ] ; e l s e break ; p=q ; q=p < < 1; } Heap [ p ] = a ; } int GetTopFromHeap ( ) { int TopElement = Heap [ 1 ] ; Heap [ 1 ] = Heap [ HeapSize −−]; HeapDown ( 1 ) ; return TopElement ; } void BuildHeap ( ) // Remember t o Let HeapSize = N { for ( int i=HeapSize ; i >0; i −−) HeapDown ( i ) ; } 1.6 Winner Tree const int i n f =10000000; const int maxsize =1 0 4 8 5 7 6 ; // 2 ˆ f l o o r ( l o g ( n ) ) int heap [ maxsize ∗ 2 ] , pos [ maxsize ∗ 2 ] , n , b a s e ; void Update ( int i ) { int j=i <<1; i f ( heap [ j +1]<heap [ j ] ) j ++; heap [ i ]= heap [ j ] ; pos [ i ]= pos [ j ] ; } int GetTopFromHeap ( int & ps ) { int r e t=heap [ 1 ] , p=pos [ 1 ] ; ps=p ; heap [ p]= i n f ; while ( p > 1 ) { p>>=1; Update ( p ) ; } return r e t ; } int main ( ) { int i , j ; c i n >> n ; fo r ( b a s e =1; base<n ; base <<=1); base −−; fo r ( i=b a s e +1; i <=(base <<1)+1; i ++) { pos [ i ]= i ; i f ( i<=b a s e+n ) c i n >> heap [ i ] ; e l s e heap [ i ]= i n f ; } fo r ( i=b a s e ; i >0; i −−) Update ( i ) ; fo r ( i =1; i<=n ; i ++) cout<<GetTopFromHeap ( j )<<e n d l ; return 0 ; } 9 1.7 Digital Tree #define maxlen 1 0 0 #define maxsize 1 0 0 0 0 0 0 #define DataType int char t r e e [ maxsize ] , s [ maxlen ] ; int son [ maxsize ] , bro [ maxsize ] , num , k , n ; DataType data [ maxsize ] ; DataType f i n d ( const char∗ s ) { int i , j =0; fo r ( i =0; s [ i ] ; i ++) { j=son [ j ] ; while ( j && t r e e [ j ] ! = s [ i ] ) j=bro [ j ] ; i f ( ! j ) return −1; } return data [ j ] ; } void add ( const char∗ s , DataType x ) { int i , j =0,p ; fo r ( i =0; s [ i ] ; i ++) { p=j ; j=son [ j ] ; while ( j && t r e e [ j ] ! = s [ i ] ) j=bro [ j ] ; if (! j ) { t r e e [++num]= s [ i ] ; son [ num] = 0 ; bro [ num]= son [ p ] ; son [ p]=num ; data [ num]= −1; j=num ; } } data [ j ]=x ; } void i n i t ( ) { num= 0 ; bro [ num ] = 0 ; son [ num ] = 0 ; data [ 0 ] = − 1 ; } 1.8 Segment Tree int c c [ 1 < < 2 2 ] ,m, n ; // memset cc f i r s t void update ( int i i , int s , int t , int s s , int t t , bool i n s e r t ) { i f ( s s >t t ) return ; int mid ( ( s+t ) / 2 ) ; i f ( s==s s && t==t t ) { i f ( i n s e r t ) c c [ i i ]= t−s + 1 ; e l s e c c [ i i ] = 0 ; return ; } i f ( c c [ i i ]==0) i f ( ! i n s e r t ) return ; e l s e c c [ i i ∗2]= c c [ i i ∗2+1]=0; e l s e i f ( c c [ i i ]==t−s +1) i f ( i n s e r t ) return ; e l s e { c c [ i i ∗2]=mid−s + 1 ; c c [ i i ∗2+1]= t−mid ; } update ( i i ∗ 2 , s , mid , s s , m i n ( mid , t t ) , i n s e r t ) ; update ( i i ∗2+1 ,mid+1, t , max ( mid+1, s s ) , t t , i n s e r t ) ; c c [ i i ]= c c [ i i ∗2]+ c c [ i i ∗ 2 + 1 ] ; } int query ( int i i , int s , int t , int s s , int t t ) { i f ( s s >t t ) return 0 ; int mid ( ( s+t ) / 2 ) ; i f ( s==s s && t==t t ) return c c [ i i ] ; i f ( c c [ i i ]==0) c c [ i i ∗ 2 ] = c c [ i i ∗ 2 + 1 ] = 0 ; i f ( c c [ i i ]==t−s +1) { c c [ i i ∗2]=mid−s + 1 ; c c [ i i ∗2+1]= t−mid ; } return query ( i i ∗ 2 , s , mid , s s , m i n ( mid , t t ) ) +query ( i i ∗2+1 ,mid+1, t , max ( mid+1, s s ) , t t ) ; } 10 1.9 Segment Tree in IOI’2001 // upper : maximum p o s s i b l e r i g h t p o i n t o f i n t e r v a l s int upper , t r e e [ m a x i n t e r v a l + 1 ] ; void i n i t ( ) { upper = 0 ; memset ( t r e e , 0 , s i z e o f ( t r e e ) ) ; } void update ( int r , int x ) // sum [ 1 . . r ] += x { while ( r<=upper ) { t r e e [ r]+=x ; r+=(r &( r ˆ ( r − 1 ) ) ) ; } } int sum ( int r ) // r e t u r n sum [ 1 . . r ] { int r e s = 0 ; while ( r > 0 ) { r e s+=t r e e [ r ] ; r −=(r &( r ˆ ( r − 1 ) ) ) ; } return r e s ; } 1.10 Union-Find Set int rank [ maxn ] , pnt [ maxn ] ; void makeset ( int x ) { rank [ pnt [ x]=x ] = 0 ; } int f i n d ( int x ) { int px=x , i ; while ( px!= pnt [ px ] ) px=pnt [ px ] ; while ( x!=px ) { i=pnt [ x ] ; pnt [ x]=px ; x=i ; } ; return px ; } void merge ( int x , int y ) // or j u s t pnt [ f i n d ( x )]= f i n d ( y ) { i f ( rank [ x=f i n d ( x )] > rank [ y=f i n d ( y ) ] ) pnt [ y]=x ; e l s e { pnt [ x]=y ; rank [ y]+=( rank [ x]==rank [ y ] ) ; } ; } 1.11 Quick Sort void q u i c k s o r t ( int b , int e , int a [ ] ) { int i=b , j=e , x=a [ ( b+e ) / 2 ] ; do{ while ( a [ i ]<x ) i ++; while ( a [ j ]>x ) j −−; i f ( i<=j ) s t d : : swap ( a [ i ++],a [ j − −]); } while ( i <j ) ; i f ( i <e ) q u i c k s o r t ( i , e , a ) ; i f ( j >b ) q u i c k s o r t ( b , j , a ) ; } 11 1.12 Merge Sort void s o r t ( int b , int e ) { i f ( e−b<=0) return ; int mid=(b+e ) / 2 , p1=b , p2=mid+1, i=b ; s o r t ( b , mid ) ; s o r t ( mid+1, e ) ; while ( p1<=mid | | p2<=e ) i f ( p2>e | | ( p1<=mid && a [ p1]<=a [ p2 ] ) ) t [ i ++]=a [ p1 ++]; e l s e t [ i ++]=a [ p2 ++]; fo r ( i=b ; i<=e ; i ++)a [ i ]= t [ i ] ; } 1.13 Radix Sort #define b a s e (1 < <16) int n , a [ maxn ] , t [ maxn ] , bucket [ b a s e + 2 ] ; void RadixSort ( int n , int a [ ] , int t [ ] , int bucket [ ] ) { int k , i , j ; fo r ( j =0; j <b a s e ; j ++) bucket [ j ] = 0 ; fo r ( k=base −1, i = 0 ; i < 2 ; i ++,k<<=16){ f o r ( j =0; j <n ; j ++) bucket [ a [ j ]&k]++; f o r ( j =1; j <b a s e ; j ++) bucket [ j ]+=bucket [ j − 1 ] ; f o r ( j=n−1; j >=0; j −−) t[−−bucket [ a [ j ]&k ] ] = a [ j ] ; f o r ( j =0; j <n ; j ++) a [ j ]= t [ j ] ; } } 1.14 Select K th Smallest Element int s e l e c t ( int ∗ a , int b , int e , int k ) { i f ( b==e ) return a [ b ] ; int x = a [ b+rand ()%( e−b + 1 ) ] , i = b , j = e ; i −−; j ++; while ( i <j ) { while ( a[++ i ] < x ) ; while ( a[−− j ] > x ) ; i f ( i <j ) s t d : : swap ( a [ i ] , a [ j ] ) ; } i f ( j==e ) j −−; i = j −b+1; i f ( k <= i ) return s e l e c t ( a , b , j , k ) ; e l s e return s e l e c t ( a , j +1 , e , k−i ) ; } 1.15 KMP int f a i l [ maxlen ] ; void m a k e f a i l ( char ∗ t , int l t ) { −−t ; fo r ( int i =1, j =0; i<=l t ; i ++, j ++){ f a i l [ i ]= j ; while ( j >0 && t [ i ] ! = t [ j ] ) j= f a i l [ j ] ; } } // s t a r t matching p a t t e r n T i n S [ i . . ) // r e t u r n match pos or l o n g e s t match l e n g t h w i t h c o r r e s p o n d i n g pos 12 int kmp( char ∗ s , int l s , char ∗ t , int l t , int i , int & l o n g e s t , int & l p ) { l o n g e s t = l p = 0; − − s ; −− t ; fo r ( int j = 1 ; i<=l s ; i ++, j ++) { while ( j >0 && s [ i ] ! = t [ j ] ) j= f a i l [ j ] ; i f ( j >l o n g e s t ) { l o n g e s t = j ; l p = i −j ; } i f ( j==l t ) return i −l t ; } return −1; } 1.16 Suffix Sort SuffixSort : input s[0..n) , output id[0..n) #define nb next // ” new b u c k e t ” o v e r l a i d on ” n e x t ” #define head h e i g h t // head i s n e v e r used when computing h e i g h t #define rank b // a f t e r S u f f i x S o r t , ” rank ” o v e r l a i d on ” b u c k e t ” char s [ maxn ] ; int n , i d [ maxn ] , h e i g h t [ maxn ] , b [ maxn ] , next [ maxn ] ; bool cmp( const int & i , const int & j ) { return s [ i ]< s [ j ] ; } void S u f f i x S o r t ( ) { int i , j , k , h ; fo r ( i = 0 ; i <n ; i ++) i d [ i ]= i ; s t d : : s o r t ( id , i d+n , cmp ) ; fo r ( i = 0 ; i <n ; i ++) i f ( i ==0 || s [ id [ i ] ] ! = s [ id [ i − 1 ] ] ) b [ id [ i ] ] = i ; else b [ id [ i ]]=b [ id [ i −1]]; fo r ( h = 1 ; h<n ; h<<=1) { f o r ( i =0; i <n ; i ++) head [ i ]= next [ i ]= −1; f o r ( i=n − 1 ; i >=0; i −−) i f ( i d [ i ] ) { j = i d [ i ]−h ; i f ( j < 0 ) j+=n ; next [ j ] = head [ b [ j ] ] ; head [ b [ j ] ] = j ; } j=n−h ; next [ j ] = head [ b [ j ] ] ; head [ b [ j ] ] = j ; f o r ( i=k = 0 ; i <n ; i ++) i f ( head [ i ] >=0 ) f o r ( j=head [ i ] ; j >=0; j=next [ j ] ) i d [ k++]= j ; f o r ( i = 0 ; i <n ; i ++) i f ( i >0 && i d [ i ]+h<n && i d [ i −1]+h<n && b [ i d [ i ] ] = = b [ i d [ i −1]] && b [ i d [ i ]+h ] == b [ i d [ i −1]+h ] ) nb [ i d [ i ] ] = nb [ i d [ i − 1 ] ] ; e l s e nb [ i d [ i ] ] = i ; f o r ( i = 0 ; i <n ; i ++) b [ i ] = nb [ i ] ; } } GetHeight : height[i] = LCP (s[id[i]], s[id[i] − 1] void GetHeight ( ) { int i , j , h ; h e i g h t [ 0 ] = 0 ; fo r ( i = 0 ; i <n ; i ++) rank [ i d [ i ] ] = i ; fo r ( h =0 , i = 0 ; i <n ; i ++ ) i f ( rank [ i ] > 0 ) { j = i d [ rank [ i ] − 1 ] ; while ( s [ i+h ] == s [ j+h ] ) + + h ; h e i g h t [ rank [ i ] ] = h ; i f ( h>0 ) −−h ; } } 13 Chapter 2 Graph Theory and Network Algorithms 2.1 SSSP — Dijkstra + Binary Heap const int i n f = 1 0 0 0 0 0 0 0 0 0 ; int n ,m, num , l e n , next [ maxm ] , ev [ maxm ] , ew [ maxm ] ; int v a l u e [ maxn ] , mk [ maxn ] , nbs [ maxn ] , ps [ maxn ] , heap [ maxn ] ; void update ( int r ) { int q=ps [ r ] , p=q>>1; while ( p && v a l u e [ heap [ p ]] > v a l u e [ r ] ) { ps [ heap [ p ] ] = q ; heap [ q]= heap [ p ] ; q=p ; p=q>>1; } heap [ q]= r ; ps [ r ]=q ; } int getmin ( ) { int r e t=heap [ 1 ] , p=1,q=2, r=heap [ l e n −−]; while ( q<=l e n ) { i f ( q<l e n && v a l u e [ heap [ q+1]] < v a l u e [ heap [ q ] ] ) q++; i f ( v a l u e [ heap [ q ]] < v a l u e [ r ] ) { ps [ heap [ q ] ] = p ; heap [ p]= heap [ q ] ; p=q ; q=p<<1; } e l s e break ; } heap [ p]= r ; ps [ r ]=p ; return r e t ; } void d i j k s t r a ( int s r c , int d s t ) { int i , j , u , v ; fo r ( i =1; i<=n ; i ++) { v a l u e [ i ]= i n f ; mk [ i ]= ps [ i ] = 0 ; } ; v a l u e [ s r c ] = 0 ; heap [ l e n =1]= s r c ; ps [ s r c ] = 1 ; while ( ! mk [ d s t ] ) { i f ( l e n ==0) return ; u=getmin ( ) ; mk [ u ] = 1 ; f o r ( j=nbs [ u ] ; j ; j=next [ j ] ) { v=ev [ j ] ; i f ( ! mk [ v ] && v a l u e [ u]+ew [ j ]< v a l u e [ v ] ) { i f ( ps [ v ]==0){ heap[++ l e n ]=v ; ps [ v]= l e n ; } v a l u e [ v]= v a l u e [ u]+ew [ j ] ; update ( v ) ; } } } } 14 void r e a d d a t a ( ) { int i , u , v ,w ; c i n >>n>>m; num=0; fo r ( i =1; i<=n ; i ++) nbs [ i ] = 0 ; while (m−−){ c i n >>u>>v>>w; next[++num]= nbs [ u ] ; nbs [ u]=num ; ev [ num]=v ; ew [ num]=w; } d i j k s t r a ( 1 , n ) ; // Minimum D i s t a n c e s a v e d a t v a l u e [ 1 . . n ] } 2.2 SSSP — Bellman Ford + Queue const int maxn = maxm = 1000005 const int i n f = 1000000000 int nbs [ maxn ] , next [ maxm ] , v a l u e [ maxn ] , open [ maxn ] , open1 [ maxn ] ; int ev [ maxm ] , ew [ maxm ] , mk [ maxn ] , n ,m, num , cur , t a i l ; void BellmanFord ( int s r c ) { int i , j , k , l , t , u , v , p=0; fo r ( i =1; i<=n ; i ++) { v a l u e [ i ]= i n f ; mk [ i ] = 0 ; } v a l u e [ s r c ]= t a i l = 0 ; open [ 0 ] = s r c ; while(++p , t a i l >=0){ f o r ( i =0; i<=t a i l ; i ++) open1 [ i ]= open [ i ] ; f o r ( c u r =0, t=t a i l , t a i l =−1; cur<=t ; c u r++) f o r ( u=open1 [ c u r ] , i=nbs [ u ] ; i ; i=next [ i ] ) { v=ev [ i ] ; i f ( v a l u e [ u]+ew [ i ]< v a l u e [ v ] ) { v a l u e [ v]= v a l u e [ u]+ew [ i ] ; i f (mk [ v ] ! = p ) { open[++ t a i l ]=v ; mk [ v]=p ; } } } } } 2.3 MST — Kruskal #define maxn 1 0 0 0 0 0 5 #define maxm 1 0 0 0 0 0 5 int i d [ maxm ] , eu [ maxm ] , ev [ maxm ] , ew [ maxm ] , n ,m, pnt [ maxn ] ; int cmp( const int & i , const int & j ) { return ew [ i ]<ew [ j ] ; } int f i n d ( int x ) { i f ( x!= pnt [ x ] ) pnt [ x]= f i n d ( pnt [ x ] ) ; return pnt [ x ] ; } int Kruskal ( ) { int r e t =0, i , j , p ; fo r ( i =1; i<=n ; i ++) pnt [ i ]= i ; // node [ 1 . . n ] fo r ( i =0; i <m; i ++) i d [ i ]= i ; // ew [ 0 . . m−1] s t d : : s o r t ( id , i d+m, cmp ) ; fo r ( j =−1, i = 1 ; i <n ; i ++){ while ( p=i d [++ j ] , f i n d ( eu [ p])== f i n d ( ev [ p ] ) ) ; r e t+=ew [ p ] ; pnt [ f i n d ( ev [ p ] ) ] = f i n d ( eu [ p ] ) ; } return r e t ; } 15 2.4 Minimum Directed Spanning Tree int n , g [ maxn ] [ maxn ] , used [ maxn ] , p a s s [ maxn ] , eg [ maxn ] , more , queue [ maxn ] ; void combine ( int id , int & sum ) { int t o t = 0 , from , i , j , k ; fo r ( ; i d !=0&&! p a s s [ i d ] ; i d=eg [ i d ] ) { queue [ t o t++]=i d ; p a s s [ i d ] = 1 ; } fo r ( from = 0 ; from<t o t&&queue [ from ] ! = i d ; from ++); i f ( from==t o t ) return ; more = 1 ; fo r ( i=from ; i <t o t ; i ++) { sum+=g [ eg [ queue [ i ] ] ] [ queue [ i ] ] ; i f ( i != from ) { used [ queue [ i ] ] = 1 ; f o r ( j = 1 ; j <= n ; j ++) i f ( ! used [ j ] ) i f ( g [ queue [ i ] ] [ j ]<g [ i d ] [ j ] ) g [ i d ] [ j ]=g [ queue [ i ] ] [ j ] ; } } fo r ( i = 1 ; i<=n ; i ++) i f ( ! used [ i ]&& i != i d ) { f o r ( j=from ; j <t o t ; j ++){ k=queue [ j ] ; i f ( g [ i ] [ i d ]>g [ i ] [ k]−g [ eg [ k ] ] [ k ] ) g [ i ] [ i d ]=g [ i ] [ k]−g [ eg [ k ] ] [ k ] ; } } } int msdt ( int r o o t ) { // r e t u r n t h e t o t a l l e n g t h o f MDST int i , j , k , sum = 0 ; memset ( used , 0 , s i z e o f ( used ) ) ; fo r ( more = 1 ; more ; ) { more = 0 ; memset ( eg , 0 , s i z e o f ( eg ) ) ; f o r ( i = 1 ; i <= n ; i ++) i f ( ! used [ i ] && i ! = r o o t ) { f o r ( j = 1 , k = 0 ; j <= n ; j ++) i f ( ! used [ j ] && i ! = j ) if ( k == 0 || g [ j ] [ i ] < g [ k ] [ i ] ) k = j ; eg [ i ] = k ; } memset ( pass , 0 , s i z e o f ( p a s s ) ) ; f o r ( i =1; i<=n ; i ++) i f ( ! used [ i ]&&! p a s s [ i ]&& i != r o o t ) combine ( i , sum ) ; } fo r ( i = 1 ; i<=n ; i ++) i f ( ! used [ i ] && i != r o o t ) sum+=g [ eg [ i ] ] [ i ] ; return sum ; } 2.5 Maximum Matching on Bipartite Graph int nx , ny ,m, g [MAXN] [MAXN] , sy [MAXN] , cx [MAXN] , cy [MAXN] ; int path ( int u ) { fo r ( int v=1;v<=ny ; v++) i f ( g [ u ] [ v ] & & ! sy [ v ] ) { sy [ v ] = 1 ; i f ( ! cy [ v ] | | path ( cy [ v ] ) ) { cx [ u]=v ; cy [ v]=u ; return 1 ; } } return 0 ; } int MaximumMatch ( ) { int i , r e t =0; memset ( cx , 0 , s i z e o f ( cx ) ) ; memset ( cy , 0 , s i z e o f ( cy ) ) ; fo r ( i =1; i<=nx ; i ++) i f ( ! cx [ i ] ) { memset ( sy , 0 , s i z e o f ( sy ) ) ; r e t+=path ( i ) ; } return r e t ; } 16 2.6 Maximum Cost Perfect Matching on Bipartite Graph int cx [ maxn ] , cy [ maxn ] , sx [ maxn ] , sy [ maxn ] , l x [ maxn ] , l y [ maxn ] ; int nx , ny , match , g [ maxn ] [ maxn ] ; int path ( int { sx [ u ] = 1 ; sy [ v ] = 1 ; } return } u) f o r ( int v=1;v<=ny ; v++) i f ( g [ u ] [ v]== l x [ u]+ l y [ v ] & & ! sy [ v ] ) { i f ( ! cy [ v ] | | path ( cy [ v ] ) ) { cx [ u]=v ; cy [ v]=u ; return 1 ; } 0; void KuhnMunkres ( ) { int i , j , u , min ; memset ( lx , 0 , s i z e o f ( l x ) ) ; memset ( ly , 0 , s i z e o f ( l y ) ) ; memset ( cx , 0 , s i z e o f ( cx ) ) ; memset ( cy , 0 , s i z e o f ( cy ) ) ; fo r ( i =1; i<=nx ; i ++) for ( j =1; j<=ny ; j ++) i f ( l x [ i ]<g [ i ] [ j ] ) l x [ i ]=g [ i ] [ j ] ; fo r ( match =0 , u = 1 ; u<=nx ; u++) i f ( ! cx [ u ] ) { memset ( sx , 0 , s i z e o f ( sx ) ) ; memset ( sy , 0 , s i z e o f ( sy ) ) ; while ( ! path ( u ) ) { min=0 x 3 f f f f f f f ; f o r ( i =1; i<=nx ; i ++) i f ( sx [ i ] ) f o r ( j =1; j<=ny ; j ++) i f ( ! sy [ j ] ) i f ( l x [ i ]+ l y [ j ]−g [ i ] [ j ]<min ) min=l x [ i ]+ l y [ j ]−g [ i ] [ j ] ; f o r ( i =1; i<=nx ; i ++) i f ( sx [ i ] ) { l x [ i ]−=min ; sx [ i ] = 0 ; } f o r ( j =1; j<=ny ; j ++) i f ( sy [ j ] ) { l y [ j ]+=min ; sy [ j ] = 0 ; } }; } } 2.7 Maximum Matching on General Graph // t o t a l i s t h e maximum c a r d i n a l i t y , p [ 1 . . n ] means a match : i <−> p [ i ] int g [ maxn ] [ maxn ] , p [ maxn ] , l [ maxn ] [ 3 ] , n , t o t a l , s t a t u s [ maxn ] , v i s i t e d [ maxn ] ; void s o l v e ( ) { int i , j , k , p a s s ; memset ( p , 0 , s i z e o f ( p ) ) ; do { i =0; do { i f ( p[++ i ] ) p a s s = 0 ; e l s e { memset ( l , 0 , s i z e o f ( l ) ) ; l [ i ] [ 2 ] = 0 x f f ; p a s s=path ( i ) ; for ( j =1; j<=n ; j ++) for ( k=1;k<=n ; k++) i f ( g [ j ] [ k ] < 0 ) g [ j ] [ k]=−g [ j ] [ k ] ; }; } while ( i !=n && ! p a s s ) ; i f ( p a s s ) t o t a l +=2; } while ( i !=n && t o t a l !=n ) ; } void upgrade ( int r ) { int j=r , i=l [ r ] [ 1 ] ; fo r ( p [ i ]= j ; l [ i ] [ 2 ] < 0 x f f ; ) { p [ j ]= i ; j=l [ i ] [ 2 ] ; i=l [ j ] [ 1 ] ; p [ i ]= j ; } p [ j ]= i ; } 17 int path ( int r ) { int i , j , k , v , t , q u i t ; memset ( s t a t u s , 0 , s i z e o f ( s t a t u s ) ) ; s t a t u s [ r ] = 2 ; do { q u i t =1; f o r ( i =1; i<=n ; i ++) i f ( s t a t u s [ i ] >1) f o r ( j =1; j<=n ; j ++) i f ( g [ i ] [ j ]>0 && p [ j ] ! = i ) i f ( s t a t u s [ j ]==0) { i f ( p [ j ]==0){ l [ j ] [ 1 ] = i ; upgrade ( j ) ; return 1 ; } e l s e i f (p [ j ] >0) { g [ i ] [ j ]=g [ j ] [ i ]= −1; s t a t u s [ j ] = 1 ; l [ j ] [ 1 ] = i ; g [ j ] [ p [ j ] ] = g [ p [ j ] ] [ j ]= −1; l [p[ j ]][2]= j ; status [ p [ j ]]=2; q u i t =0; } } else i f ( s t a t u s [ j ] >1 && ( s t a t u s [ i ]+ s t a t u s [ j ] <6)){ q u i t = 0 ; g [ i ] [ j ]=g [ j ] [ i ]= −1; memset ( v i s i t e d , 0 , s i z e o f ( v i s i t e d ) ) ; visited [ i ]=1; k=i ; v=2; while ( l [ k ] [ v ] ! = 0 x f f ) { k=l [ k ] [ v ] ; v=3−v ; v i s i t e d [ k ] = 1 ; } k=j ; v=2; while ( ! v i s i t e d [ k ] ) { k=l [ k ] [ v ] ; v=3−v ; } if ( status [ i ]!=3) l [ i ][1]= j ; if ( status [ j ]!=3) l [ j ][1]= i ; s t a t u s [ i ]= s t a t u s [ j ] = 3 ; t=i ; v=2; while ( t !=k ) { i f ( s t a t u s [ l [ t ] [ v ] ] ! = 3 ) l [ l [ t ] [ v ] ] [ v]= t ; t=l [ t ] [ v ] ; s t a t u s [ t ] = 3 ; v=3−v ; } t=j ; v=2; while ( t !=k ) { i f ( s t a t u s [ l [ t ] [ v ] ] ! = 3 ) l [ l [ t ] [ v ] ] [ v]= t ; t=l [ t ] [ v ] ; s t a t u s [ t ] = 3 ; v=3−v ; } } } while ( ! q u i t ) ; return 0 ; } 2.8 Maximum Flow — Ford Fulkson in Matrix // Remember t o memset C[ maxn ] [ maxn ] f o r a new c a s e int c [ maxn ] [ maxn ] , f [ maxn ] [ maxn ] , pnt [ maxn ] , open [ maxn ] , d [ maxn ] , mk [ maxn ] ; int maxflow ( int n , int s , int t ) { int cur , t a i l , i , j , u , v , f l o w = 0 ; memset ( f , 0 , s i z e o f ( f ) ) ; do { memset (mk, 0 , s i z e o f (mk ) ) ; memset ( d , 0 , s i z e o f ( d ) ) ; open [ 0 ] = s ; mk [ s ] = 1 ; d [ s ]=0 x 3 f f f f f f f ; f o r ( pnt [ s ]= c u r= t a i l = 0 ; cur<=t a i l && !mk [ t ] ; c u r++) f o r ( u=open [ c u r ] , v=1;v<=n ; v++) i f ( ! mk [ v]&& f [ u ] [ v]< c [ u ] [ v ] ) { mk [ v ] = 1 ; open[++ t a i l ]=v ; pnt [ v]=u ; i f ( d [ u]< c [ u ] [ v]− f [ u ] [ v ] ) d [ v]=d [ u ] ; e l s e d [ v]= c [ u ] [ v]− f [ u ] [ v ] ; } i f ( ! mk [ t ] ) break ; f l o w+=d [ t ] ; f o r ( u=t ; u!= s ; ) { v=u ; u=pnt [ v ] ; f [ u ] [ v]+=d [ t ] ; f [ v ] [ u]=− f [ u ] [ v ] ; } } while ( d [ t ] > 0 ) ; return f l o w ; } 18 2.9 Maximum Flow — Ford Fulkson in Link #define maxn 1 0 0 0 #define maxm 2 ∗ maxn∗maxn int c [ maxm ] , f [ maxm ] , ev [ maxm ] , be [ maxm ] , next [ maxm ] , num=0; int nbs [ maxn ] , pnt [ maxn ] , open [ maxn ] , d [ maxn ] , mk [ maxn ] ; void AddEdge ( int u , int v , int c c ) // Remember t o s e t nbs [ 1 . . n]=num=0 { next[++num]= nbs [ u ] ; nbs [ u]=num ; be [ num]=num+1; ev [ num]=v ; c [ num]= c c ; f [ num] = 0 ; next[++num]= nbs [ v ] ; nbs [ v]=num ; be [ num]=num−1; ev [ num]=u ; c [ num ] = 0 ; f [ num] = 0 ; } int maxflow ( int n , int s , int t ) { int cur , t a i l , i , j , u , v , f l o w = 0 ; // f has been s e t z e r o when AddEdge do { memset (mk, 0 , s i z e o f (mk ) ) ; memset ( d , 0 , s i z e o f ( d ) ) ; open [ 0 ] = s ; mk [ s ] = 1 ; d [ s ]=0 x 3 f f f f f f f ; f o r ( pnt [ s ]= c u r= t a i l = 0 ; cur<=t a i l && !mk [ t ] ; c u r++) f o r ( u=open [ c u r ] , j=nbs [ u ] ; j ; j=next [ j ] ) { v=ev [ j ] ; i f ( ! mk [ v]&& f [ j ]< c [ j ] ) { mk [ v ] = 1 ; open[++ t a i l ]=v ; pnt [ v]= j ; i f ( d [ u]< c [ j ]− f [ j ] ) d [ v]=d [ u ] ; e l s e d [ v]= c [ j ]− f [ j ] ; } } i f ( ! mk [ t ] ) break ; f l o w+=d [ t ] ; f o r ( u=t ; u!= s ; u=ev [ be [ j ] ] ) { j=pnt [ u ] ; f [ j ]+=d [ t ] ; f [ be [ j ]]=− f [ j ] ; } } while ( d [ t ] > 0 ) ; return f l o w ; } 19 2.10 Minimum Cost Maximum Flow in Matrix const int i n f =0 x 3 f f f f f f f ; int c [ maxn ] [ maxn ] , f [ maxn ] [ maxn ] ,w[ maxn ] [ maxn ] , pnt [ maxn ] ; int v a l u e [ maxn ] , d [ maxn ] , mk [ maxn ] , open [ maxn ] , o l d q u e [ maxn ] ; void m i n c o s t ( int n , int s , int t , int & flow , int & c o s t ) { int cur , t a i l , t l , i , j , u , v ; memset ( f , 0 , s i z e o f ( f ) ) ; f l o w = 0 ; c o s t =0; do { memset ( d , 0 , s i z e o f ( d ) ) ; f o r ( i =1; i<=n ; i ++) v a l u e [ i ]= i n f ; open [ 0 ] = s ; d [ s ]=0 x 3 f f f f f f f ; t a i l =v a l u e [ s ] = 0 ; while ( t a i l >=0){ memset (mk, 0 , s i z e o f (mk ) ) ; memcpy( oldque , open , s i z e o f ( open ) ) ; f o r ( t l=t a i l , pnt [ s ]= c u r =0, t a i l =−1; cur<=t l ; c u r++) f o r ( u=o l d q u e [ c u r ] , v=1;v<=n ; v++) i f ( f [ u ] [ v]< c [ u ] [ v ] && v a l u e [ u]< i n f && v a l u e [ u]+w[ u ] [ v]< v a l u e [ v ] ) { i f ( ! mk [ v ] ) { mk [ v ] = 1 ; open[++ t a i l ]=v ; } ; pnt [ v]=u ; v a l u e [ v]= v a l u e [ u]+w [ u ] [ v ] ; i f ( d [ u]< c [ u ] [ v]− f [ u ] [ v ] ) d [ v]=d [ u ] ; e l s e d [ v]= c [ u ] [ v]− f [ u ] [ v ] ; } } i f ( v a l u e [ t]== i n f ) return ; f l o w+=d [ t ] ; c o s t+=d [ t ] ∗ v a l u e [ t ] ; f o r ( u=t ; u!= s ; ) { v=u ; u=pnt [ v ] ; f [ u ] [ v]+=d [ t ] ; f [ v ] [ u]=− f [ u ] [ v ] ; i f ( f [ u ] [ v ] < 0 ) w[ u ] [ v]=−w [ v ] [ u ] ; e l s e i f ( f [ v ] [ u ] < 0 ) w[ v ] [ u]=−w [ u ] [ v ] ; } } while ( d [ t ] > 0 ) ; } 20 2.11 Minimum Cost Maximum Flow in Link #define maxn 3 5 0 #define maxm 1 0 0 0 0 0 // maxm∗2 const int i n f =0 x 3 f f f f f f f ; int c [ maxm ] , f [ maxm ] ,w[ maxm ] , ev [ maxm ] , be [ maxm ] , next [ maxm ] , v a l u e [ maxn ] ; int nbs [ maxn ] , pnt [ maxn ] , open [ maxn ] , o l d q u e [ maxn ] , d [ maxn ] , mk [ maxn ] , num=0; void AddEdge ( int u , int v , int cc , int ww) // Remember t o s e t nbs [ 1 . . n]=num=0 { next[++num]= nbs [ u ] ; nbs [ u]=num ; be [ num]=num+1; ev [ num]=v ; c [ num]= c c ; f [ num ] = 0 ; w [ num]=ww; next[++num]= nbs [ v ] ; nbs [ v]=num ; be [ num]=num−1; ev [ num]=u ; c [ num ] = 0 ; f [ num ] = 0 ; w [ num]=−ww; } void m i n c o s t ( int n , int s , int t , int & flow , int & c o s t ) { int cur , t a i l , t l , i , j , u , v ; memset ( f , 0 , s i z e o f ( f ) ) ; f l o w = 0 ; c o s t =0; do { memset ( d , 0 , s i z e o f ( d ) ) ; f o r ( i =1; i<=n ; i ++) v a l u e [ i ]= i n f ; open [ 0 ] = s ; d [ s ]=0 x 3 f f f f f f f ; t a i l =v a l u e [ s ] = 0 ; while ( t a i l >=0){ memset (mk, 0 , s i z e o f (mk ) ) ; memcpy( oldque , open , s i z e o f ( open ) ) ; f o r ( t l=t a i l , pnt [ s ]= c u r =0, t a i l =−1; cur<=t l ; c u r++) f o r ( u=o l d q u e [ c u r ] , j=nbs [ u ] ; j ; j=next [ j ] ) { v=ev [ j ] ; i f ( f [ j ]< c [ j ] && v a l u e [ u]< i n f && v a l u e [ u]+w [ j ]< v a l u e [ v ] ) { i f ( ! mk [ v ] ) { mk [ v ] = 1 ; open[++ t a i l ]=v ; } ; pnt [ v]= j ; v a l u e [ v]= v a l u e [ u]+w [ j ] ; i f ( d [ u]< c [ j ]− f [ j ] ) d [ v]=d [ u ] ; e l s e d [ v]= c [ j ]− f [ j ] ; } } } i f ( v a l u e [ t]== i n f ) return ; f l o w+=d [ t ] ; c o s t+=d [ t ] ∗ v a l u e [ t ] ; f o r ( u=t ; u!= s ; u=ev [ be [ j ] ] ) { j=pnt [ u ] ; f [ j ]+=d [ t ] ; f [ be [ j ]]=− f [ j ] ; } } while ( d [ t ] > 0 ) ; } 2.12 Recognizing Chordal Graph int n ,m, mk [ maxn ] , d e g r e e [ maxn ] ,PEO[ maxn ] , g [ maxn ] [ maxn ] ; int Chordal ( ) { memset (mk, 0 , s i z e o f (mk ) ) ; memset ( d e g r e e , 0 , s i z e o f ( d e g r e e ) ) ; fo r ( int j , k , u , v , i =0; i <n ; i ++) { j =−1; u=−1; f o r ( k=0;k<n ; k++) i f ( ! mk [ k ] & & ( j < 0 | | d e g r e e [ k]> d e g r e e [ j ] ) ) j=k ; mk [ j ] = 1 ; PEO[ i ]= j ; f o r ( k=i −1;k>=0;k−−) i f ( g [ j ] [ PEO[ k ] ] ) i f ( u < 0 ) u=PEO[ k ] ; e l s e i f ( ! g [ u ] [ PEO[ k ] ] ) return 0 ; f o r ( k=0;k<n ; k++) i f ( ! mk [ k ] && g [ j ] [ k ] ) d e g r e e [ k]++; } return 1 ; } 21 2.13 DFS — Bridge int n , g [ maxn ] [ maxn ] , mk [ maxn ] , d [ maxn ] , low [ maxn ] ; int c o l o r , t i , bridgenum , b r i d g e u [ maxn ] , b r i d g e v [ maxn ] ; void d f s v i s i t ( int u , int p ) { int v , s =0, bBridge = 0 ; low [ u]=d [ u]=++ t i ; mk [ u]=− c o l o r ; fo r ( v = 1 ; v<=n ; v++) i f ( g [ u ] [ v ] && v!=p ) i f (mk [ v ]==0){ d f s v i s i t ( v , u ) ; s++; i f ( low [ v]< low [ u ] ) low [ u]= low [ v ] ; i f ( low [ v]==d [ v ] ) { b r i d g e u [ bridgenum ]=u ; b r i d g e v [ bridgenum++]=v ; } } e l s e i f ( d [ v]< low [ u ] ) low [ u]=d [ v ] ; mk [ u]= c o l o r ; } void d f s ( ) { int i , j , k ; memset (mk, 0 , s i z e o f (mk ) ) ; c o l o r=t i=bridgenum =0; fo r ( i = 1 ; i<=n ; i ++) i f ( ! mk [ i ]){ ++ c o l o r ; d f s v i s i t ( i , 0 ) ; } cout<<bridgenum<<e n d l ; } 2.14 DFS — Cutvertex int n , g [ maxn ] [ maxn ] , mk [ maxn ] , d [ maxn ] , low [ maxn ] ; int c o l o r , t i , cutvertexnum , c u t v e r t e x l i s t [ maxn ] ; void d f s v i s i t ( int u , int p ) { int v , s =0, bVertex = 0 ; low [ u]=d [ u]=++ t i ; mk [ u]=− c o l o r ; fo r ( v = 1 ; v<=n ; v++) i f ( g [ u ] [ v ] && v!=p ) i f (mk [ v ]==0){ d f s v i s i t ( v , u ) ; s++; i f ( low [ v]< low [ u ] ) low [ u]= low [ v ] ; i f ( low [ v]>=d [ u ] ) bVertex =1; } e l s e i f ( d [ v]< low [ u ] ) low [ u]=d [ v ] ; i f ( ( p && bVertex ) | | ( ! p && s > 1 ) ) c u t v e r t e x l i s t [ cutvertexnum++]=u ; mk [ u]= c o l o r ; } void d f s ( ) { int i , j , k ; memset (mk, 0 , s i z e o f (mk ) ) ; c o l o r=t i=cutvertexnum =0; fo r ( i = 1 ; i<=n ; i ++) i f ( ! mk [ i ]){ ++ c o l o r ; d f s v i s i t ( i , 0 ) ; } cout<<cutvertexnum<<e n d l ; fo r ( i =0; i <cutvertexnum ; i ++) cout<<c u t v e r t e x l i s t [ i ]<<” ” ; cout<<e n d l ; } 22 2.15 DFS — Block int n , g [ maxn ] [ maxn ] , mk [ maxn ] , d [ maxn ] , low [ maxn ] , l e n , que [ maxn ] ; int c o l o r , t i , cutvertexnum , c u t v e r t e x l i s t [ maxn ] , blocknum ; void d v s v i s i t ( int u , int p ) { int v , s =0, bCutvertex = 0 ; low [ u]=d [ u]=++ t i ; mk [ u]=− c o l o r ; que[++ l e n ]=u ; fo r ( v = 1 ; v<=n ; v++) i f ( g [ u ] [ v ] && v!=p ) i f (mk [ v ]==0){ d v s v i s i t ( v , u ) ; s++; i f ( low [ v]< low [ u ] ) low [ u]= low [ v ] ; i f ( low [ v]>=d [ u ] ) { while ( que [ l e n ] ! = v ) cout<<que [ l e n −−]<<” ” ; cout<<que [ l e n −−]<<” ”<<u<<e n d l ; bCutvertex = 1 ; blocknum++; } } e l s e i f ( d [ v]< low [ u ] ) low [ u]=d [ v ] ; i f ( ( p && bCutvertex ) | | ( ! p && s > 1 ) ) c u t v e r t e x l i s t [ cutvertexnum++]=u ; mk [ u]= c o l o r ; } void d f s ( ) { int i , j , k ; memset (mk, 0 , s i z e o f (mk ) ) ; c o l o r=t i=cutvertexnum=blocknum =0; fo r ( i = 1 ; i<=n ; i ++) i f ( ! mk [ i ] ) { ++c o l o r ; l e n = 0 ; d v s v i s i t ( i , 0 ) ; i f ( l e n > 1 | | d [ i ]== t i ) { while ( l e n >1) cout<<que [ l e n −−]<<” ” ; cout<<i <<e n d l ; blocknum++; } } cout<<” Block Number : ”<<blocknum<<e n d l ; cout<<” C u t v e rt e x Number : ”<<cutvertexnum<<e n d l ; fo r ( i =0; i <cutvertexnum ; i ++) cout<<c u t v e r t e x l i s t [ i ]<<” ” ; cout<<endl<<e n d l ; } 23 2.16 DFS — Topological Sort int n , mk [ maxn ] , topo [ maxn ] , g [ maxn ] [ maxn ] , ps , topook ; void d f s ( int u ) { i f (mk [ u ] <0){ topook = 0 ; return ; } ; i f (mk [ u ] > 0 ) return ; e l s e mk [ u]= −1; fo r ( int v = 1 ; topook && v<=n ; v++) i f ( g [ u ] [ v ] ) d f s ( v ) ; topo [ ps−−]=u ; mk [ u ] = 1 ; } void t o p o s o r t ( ) { int i , j , k ; topook = 1 ; ps=n ; memset (mk, 0 , s i z e o f (mk ) ) ; fo r ( i =1; topook && i<=n ; i ++) i f ( ! mk [ i ] ) d f s ( i ) ; } int main ( ) { int i ,m, u , v ; while ( c i n >>n>>m, n && ! c i n . f a i l ( ) ) { memset ( g , 0 , s i z e o f ( g ) ) ; while (m−−){ c i n >>u>>v ; g [ u ] [ v ] = 1 ; } ; t o p o s o r t ( ) ; f o r ( i =1; i <n ; i ++) cout<<topo [ i ]<<” ” ; cout<<topo [ n]<< e n d l ; } return 0 ; } 2.17 Strongly Connected Component int g [ maxn ] [ maxn ] , n , mk [ maxn ] , l i s t [ maxn ] , num ; void back ( int v ) { mk [ v ] = 1 ; cout<<v<<” ” ; fo r ( int u = 1 ; u<=n ; u++) i f ( ! mk [ u ] && g [ u ] [ v ] ) back ( u ) ; } void d f s ( int u ) { mk [ u ] = 1 ; fo r ( int v = 1 ; v<=n ; v++) i f ( ! mk [ v ] && g [ u ] [ v ] ) d f s ( v ) ; l i s t [ num−−]=u ; } int main ( ) { int i , j , k , l ; c i n >>n ; f o r ( i =1; i<=n ; i ++) for ( j =1; j<=n ; j ++) c i n >>g [ i ] [ j ] ; memset (mk, 0 , s i z e o f (mk ) ) ; num=n ; fo r ( i =1; i<=n ; i ++) i f ( ! mk [ i ] ) d f s ( i ) ; memset (mk, 0 , s i z e o f (mk ) ) ; fo r ( i =1; i<=n ; i ++) i f ( ! mk [ l i s t [ i ] ] ) { back ( l i s t [ i ] ) ; cout<<e n d l ; } return 0 ; } 24 Chapter 3 Number Theory 3.1 Greatest Common Divisor void gcd ( int a , int b , int &d , int &x , int &y ) { i f ( b==0 ){ d=a ; x = 1 ; y = 0 ; return ; } gcd ( b , a%b , d , y , x ) ; y −= x ∗ ( a /b ) ; } 3.2 Chinese Remainder Theorem extended euclid(a, b) = ax + by int e x t e n d e d e u c l i d ( int a , int b , int &x , int &y ) { i f ( b==0){ x=1,y = 0 ; return a ; } e l s e { int r e s=e x t e n d e d e u c l i d ( b , a%b , x , y ) ; int t=x ; x=y ; y=t −(a/b ) ∗ y ; return r e s ; } } ax ≡ b (mod n) , n > 0 void m o d u l a r l i n e a r e q u a t i o n s o l v e r ( int a , int b , int n ) { int d , x , y , e , i ; d=e x t e n d e d e u c l i d ( a , n , x , y ) ; i f ( b%d ! = 0 ) cout<<”No answer ! ” ; e l s e { e=x ∗ ( b/d)%n ; // x=e i s a b a s i c s o l u t i o n f o r ( i =0; i <d ; i ++) cout <<(e+i ∗ ( n/d))%n<<e n d l ; } } Given bi , wi , i = 0 · · · len − 1 which wi > 0 , i = 0 · · · len − 1 and (wi , wj ) = 1 , i 6= j Find an x which satisfies: x ≡ bi (mod wi ), i = 0 · · · len − 1 int c h i n a ( int b [ ] , int w [ ] , int l e n ) { int i , d , x , y , x ,m, n ; x = 0 ; n = 1 ; f or ( i =0; i <l e n ; i ++) n∗=w [ i ] ; fo r ( i =0; i <l e n ; i ++){ m=n/w [ i ] ; d=e x t e n d e d e u c l i d (w[ i ] ,m, x , y ) ; x=(x+y∗m∗b [ i ])%n ; } return ( n+x%n)%n ; } 25 3.3 Prime Generator #define maxn 1 0 0 0 0 0 0 0 #define maxp 1 0 0 0 0 0 0 char mk [ maxn ] ; int prime [ maxp ] , pnum ; void GenPrime ( int n ) { int i , j , k ; pnum = 0 ; memset (mk , 0 , n +1); fo r ( i =2,k = 4 ; i<=n ; i ++,k+=i+i −1) i f ( ! mk [ i ] ) { prime [ pnum++] = i ; i f ( k<=n ) for ( j=i+i ; j<=n ; j+=i ) mk [ j ] = 1 ; } } 3.4 φ Generator Q φ(n) = n p|n (1 − p1 ), where p is a prime. φ(846720) = 193536 int Phi ( int n ) // O( S q r t (N) ) { int i , j , r e t=n ; fo r ( i =2, j = 4 ; j<=n ; i ++, j+=i+i −1) i f ( ! ( n%i ) ) { r e t = r e t / i ∗ ( i −1); while ( ! ( n%i ) ) n/= i ; } i f ( n > 1 ) r e t = r e t / n ∗ ( n −1); return r e t ; } #define maxn 1 0 0 0 0 0 0 0 #define maxp 1 0 0 0 0 0 0 int p h i [ maxn ] , prime [ maxp ] , pnum ; void GenPhi ( int n ) // O( N l o g l o g N ) { int i , j , k ; pnum = 0 ; memset ( phi , 0 , ( n+1)∗ s i z e o f ( p h i [ 0 ] ) ) ; phi [ 1 ] = 1 ; fo r ( i = 2 ; i<=n ; i ++) i f ( ! p h i [ i ] ) { prime [ pnum++] = i ; f o r ( j=i ; j<=n ; j+=i ) { i f ( ! p h i [ j ] ) p h i [ j ]= j ; p h i [ j ] = p h i [ j ] / i ∗ ( i −1); } } } 26 3.5 Discrete Logarithm #define l l o n g int64 i n l i n e int mod( int x , int n ) { return ( x%n+n)%n ; } // ax ≡ 1 (mod n) int Inv ( int a , int n ) { int d , x , y ; Gcd ( a , n , d , x , y ) ; i f ( d==1) return mod( x , n ) ; e l s e return −1; } // x ≡ ab (mod n), a, b >= 0 int ModPow( int a , int b , int n ) { l l o n g d ( 1 ) , i ( 0 ) ; while ( b>=(( l l o n g )1<< i ) ) i ++; fo r(−− i ; i >=0;−− i ) { d=d∗d%n ; i f ( b&(1<< i ) ) d=d∗ a%n ; } return d ; } // ax ≡ b (mod n), n is prime! int mexp [ 5 0 0 0 0 ] , i d [ 5 0 0 0 0 ] ; bool logcmp ( const int &a , const int &b ) { return mexp [ a]<mexp [ b ] ; } int ModLog ( int a , int b , int n ) { int i , j ,m = ( int ) c e i l ( s q r t ( n ) ) , i n v = Inv (ModPow( a ,m, n ) , n ) ; fo r ( i d [ 0 ] = 0 , mexp [ 0 ] = i =1; i <m; i ++) { i d [ i ]= i ; mexp [ i ] = ( mexp [ i −1]∗( l l o n g ) a)%n ; } s t d : : s t a b l e s o r t ( id , i d+m, logcmp ) ; s t d : : s o r t ( mexp , mexp+m) ; fo r ( i = 0 ; i <m; i ++) { // i ∗m < n j = s t d : : lower bound ( mexp , mexp+m, b)−mexp ; i f ( j <m && mexp [ j ]==b ) return i ∗m+i d [ j ] ; b = ( b ∗ ( l l o n g ) i n v )%n ; } return −1; } 27 3.6 Square Roots in Zp #define l l o n g int64 int ModPow( int a , int b , int n ) // aˆ b mod n a , b>=0 { llong d(1) , i (0); while ( b>=(( l l o n g )1<< i ) ) i ++; fo r (−− i ; i >=0;−− i ) { d=d∗d%n ; i f ( b&(1<< i ) ) d=d∗a%n ; } return d ; } // x ∗ x = a ( mod n ) n s h o u l d be a prime and gcd ( a , n)==1 int ModSqrt ( int a , int n ) { int b , k , i , x ; i f ( n==2) return a%n ; i f ( ModPow( a , ( n −1)/2 , n)==1) { i f ( n%4==3) x = ModPow( a , ( n +1)/4 , n ) ; e l s e { f o r ( b = 1 ; ModPow( b , ( n −1)/2 , n)==1; b++); i =(n − 1 ) / 2 ; k = 0 ; do { i / = 2 ; k /=2; i f ( ( ModPow( a , i , n ) ∗ ( l l o n g )ModPow( b , k , n)+1)%n==0) k+=(n −1)/2; } while ( i %2==0); x =( ModPow( a , ( i +1)/2 , n ) ∗ ( l l o n g )ModPow( b , k / 2 , n ) ) % n ; } i f ( x∗2>n ) x=n−x ; return x ; } return −1; } int main ( ) { int a , n , c a s e c , x ; c i n >> c a s e c ; while ( c a s e c −−) { c i n >> a >> n ; x = ModSqrt ( a , n ) ; i f ( x <0) c o u t << ”No r o o t ” << e n d l ; e l s e i f ( x∗2==n ) c o u t << x << e n d l ; e l s e c o u t << x << ’ ’ << n−x << e n d l ; } return 0 ; } 28 Chapter 4 Algebraic Algorithms 4.1 Linear Equations in Z2 // Gauss Elimination : L 0≤j<nn ai,j xi,j = ai,nn int m, nn , num , l i s t [ maxn ] ; char a [ maxn ] [ maxn ] ; int r e d u c e ( ) { int i , j , k , r ; fo r ( i=r = 0 ; i <nn ; i ++){ f o r ( j=r ; j <m && ! a [ j ] [ i ] ; j ++); i f ( j>=m) continue ; i f ( j >r ) for ( k=0;k<=nn ; k++) s t d : : swap ( a [ r ] [ k ] , a [ j ] [ k ] ) ; f o r (num=0,k=i ; k<=nn ; k++) i f ( a [ r ] [ k ] ) l i s t [ num++]=k ; f o r ( j =0; j <m; j ++) i f ( j != r && a [ j ] [ i ] ) f o r ( k=0;k<num ; k++) a [ j ] [ l i s t [ k ] ] ˆ = 1 ; ++r ; } fo r ( i =0; i <m; i ++) i f ( a [ i ] [ nn ] ) { f o r ( j =0; j <nn && ! a [ i ] [ j ] ; j ++); i f ( j==nn ) return 0 ; // e l s e x [ j ]=a [ i ] [ nn ] / a [ i ] [ j ] ; } return 1 ; } 29 4.2 Linear Equations in Z // Gauss Elimination : P 0≤j<nn ai,j xi,j = ai,nn int m, nn , a [ maxn ] [ maxn ] ; int gcd ( int x , int y ) { i f ( y==0) return x ; e l s e return gcd ( y , x%y ) ; } void y u e f e n ( int b [ ] , int c t ) { int i , j =0,k ; fo r ( i =0; i <c t ; i ++) i f ( b [ i ] ) i f ( j ) k=gcd ( b [ i ] , k ) ; e l s e { k=b [ i ] ; j =1;} i f ( k ! = 0 ) f o r ( i =0; i <c t ; i ++) b [ i ]/=k ; } int r e d u c e ( ) // r e t u r n 0 means no s o l u t i o n ! { int i , j , k , r , tmp ; fo r ( i=r = 0 ; i <nn ; i ++){ f o r ( j=r ; j <m && ! a [ j ] [ i ] ; j ++); i f ( j>=m) continue ; i f ( j >r ) for ( k=0;k<=nn ; k++) s t d : : swap ( a [ r ] [ k ] , a [ j ] [ k ] ) ; f o r ( j =0; j <m; j ++) i f ( j != r && a [ j ] [ i ] ) { tmp=a [ j ] [ i ] ; f o r ( k=0;k<=nn ; k++) a [ j ] [ k]=a [ j ] [ k ] ∗ a [ r ] [ i ]−tmp∗ a [ r ] [ k ] ; y u e f e n ( a [ j ] , nn +1); } ++ r ; } fo r ( i =0; i <m; i ++) i f ( a [ i ] [ nn ] ) { f o r ( j =0; j <nn && ! a [ i ] [ j ] ; j ++); i f ( j==nn ) return 0 ; // e l s e x [ j ]=a [ i ] [ nn ] / a [ i ] [ j ] ; } return 1 ; } 4.3 Linear Equations in Q Note: fraction.h contains a Fraction Class (Section 1.4 on Page 8) #include<f r a c t i o n . h> int m, nn ; F r a c t i o n a [ maxn ] [ maxn ] ; int dcmp ( F r a c t i o n x ) { return x . a ; } int r e d u c e ( ) { int i , j , k , r ; double tmp ; fo r ( i=r = 0 ; i <nn ; i ++){ f o r ( j=r ; j <m && !dcmp ( a [ j ] [ i ] ) ; j ++); i f ( j>=m) continue ; i f ( j >r ) for ( k=0;k<=nn ; k++) s t d : : swap ( a [ r ] [ k ] , a [ j ] [ k ] ) ; f o r ( j =0; j <m; j ++) i f ( j != r && dcmp ( a [ j ] [ i ] ) ) { tmp=a [ j ] [ i ] / a [ r ] [ i ] ; f o r ( k=0;k<=nn ; k++) a [ j ] [ k]=a [ j ] [ k]−tmp∗ a [ r ] [ k ] ; } ++ r ; } fo r ( i =0; i <m; i ++) i f ( dcmp ( a [ i ] [ nn ] ) ) { f o r ( j =0; j <nn && !dcmp ( a [ i ] [ j ] ) ; j ++); i f ( j==nn ) return 0 ; // e l s e x [ j ]=a [ i ] [ nn ] / a [ i ] [ j ] ; } return 1 ; } 30 4.4 Linear Equations in R const double e p s=1e −8; int m, nn ; double a [ maxn ] [ maxn ] ; int dcmp ( double x ) { i f ( x>e p s ) return 1 ; i f ( x<−e p s ) return − 1 ; return 0 ; } int r e d u c e ( ) // r i s rank { int i , j , k , r ; double tmp ; fo r ( i=r = 0 ; i <nn ; i ++){ f o r ( j=r ; j <m && !dcmp ( a [ j ] [ i ] ) ; j ++); i f ( j>=m) continue ; i f ( j >r ) for ( k=0;k<=nn ; k++) s t d : : swap ( a [ r ] [ k ] , a [ j ] [ k ] ) ; f o r ( j =0; j <m; j ++) i f ( j != r && dcmp ( a [ j ] [ i ] ) ) { tmp=a [ j ] [ i ] / a [ r ] [ i ] ; f o r ( k=0;k<=nn ; k++) a [ j ] [ k]−=tmp∗a [ r ] [ k ] ; } ++ r ; } fo r ( i =0; i <m; i ++) i f ( dcmp ( a [ i ] [ nn ] ) ) { f o r ( j =0; j <nn && !dcmp ( a [ i ] [ j ] ) ; j ++); i f ( j==nn ) return 0 ; // e l s e x [ j ]=a [ i ] [ nn ] / a [ i ] [ j ] ; } return 1 ; } 4.5 Roots of Polynomial Find the roots of fa (x) = Pn i=0 d ai xi using Newton Iterations, fb (x) = fa (x) dx const double e p s=1e −5; #define genx ( rand ( ) % 1 0 0 0 ) / 1 0 0 . 0 int dcmp ( double x ) { i f ( x>e p s ) return 1 ; e l s e i f ( x<−e p s ) return − 1 ; e l s e return 0 ; } double f ( double a [ ] , int n , double x ) { double r e t =0,xx =1; fo r ( int i =0; i<=n ; i ++){ r e t+=a [ i ] ∗ xx ; xx∗=x ; } return r e t ; } double newton ( double a [ ] , double b [ ] , int n ) { double dy , y , x=genx , l a s t x=x −1; while ( y=f ( a , n , x ) , dcmp ( l a s t x −x ) ) { l a s t x=x ; dy=f ( b , n−1,x ) ; i f ( ! dcmp ( dy ) ) x=genx ; e l s e x=x−y/dy ; } return x ; } void s o l v e ( double a [ ] , double x [ ] , int n ) { int i , j ; double b [ maxn ] ; fo r ( j=n ; j >0; j −−){ f o r ( i =0; i <j ; i ++) b [ i ]=a [ i +1]∗( i +1); x [ j −1]=newton ( a , b , j ) ; f o r ( b [ j ] = 0 , i=j − 1 ; i >=0; i −−) b [ i ]=a [ i +1]+b [ i +1]∗ x [ j − 1 ] ; f o r ( i =0; i <j ; i ++) a [ i ]=b [ i ] ; } } 31 4.6 Roots of Cubic and Quartic c0 + c1 ∗ x + c2 ∗ x2 + c3 ∗ x3 + c4 ∗ x4 = 0 The functions return the number of distinct non-complex roots and put the values into the s array. const double p i = a c o s ( − 1 . 0 ) ; // 3.141 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 double c b r t ( double x ) { i f ( x> e p s ) return pow ( x , 1 / 3 . 0 ) ; i f ( x<−e p s ) return −pow( −x , 1 / 3 . 0 ) ; return 0 ; } int S o l v e Q u a d r i c ( double c [ 3 ] , double s [ 2 ] ) { double p , q , d ; // normal form : x ˆ2 + px + q = 0 p = c [ 1 ] / ( 2 ∗ c [ 2 ] ) ; q = c [ 0 ] / c [ 2 ] ; d = p∗p−q ; i f ( dcmp ( d ) = = 0 ) { s [ 0 ] = − p ; return 1 ; } i f ( dcmp ( d ) < 0 ) return 0 ; d = sqrt ( d ) ; s [0] = − p + d ; s [1] = − p − d ; return 2 ; } int S o l v e C u b i c ( double c [ 4 ] , double s [ 3 ] ) { int i , num ; // normal form : x ˆ3 + Axˆ2 + Bx + C = 0 double sub , A, B , C , sqa , p , q , cbp , d ; A = c [2]/ c [ 3 ] ; B = c [1]/ c [ 3 ] ; C = c [0]/ c [3]; sqa = A ∗ A ; // x = y − A/ 3 => x ˆ3 + px + q = 0 p = 1 . 0 / 3 ∗ ( − 1 . 0 / 3 ∗ sqa + B ) ; q = 1 . 0 / 2 ∗ ( 2 . 0 / 2 7 ∗ A ∗ sqa − 1 . 0 / 3 ∗ A ∗ B + C ) ; cbp = p ∗ p ∗ p ; // use Cardano ’ s f o r m u l a d = q ∗ q + cbp ; i f ( dcmp ( d )==0 ) { i f ( dcmp ( q ) = = 0 ) { s [ 0 ] = 0 ; num = 1 ; } // one t r i p l e s o l u t i o n e l s e { // one s i n g l e and one d o u b l e s o l u t i o n double u = c b r t ( −q ) ; s [ 0 ] = 2 ∗ u ; s [ 1 ] = − u ; num = 2 ; } } e l s e i f ( dcmp ( d ) < 0 ) { // Casus i r r e d u c i b i l i s : t h r e e r e a l s o l u t i o n s double p h i = 1 . 0 / 3 ∗ a c o s (−q / s q r t (−cbp ) ) ; double t = 2 ∗ s q r t (−p ) ; s[ 0 ] = t ∗ cos ( phi ) ; s [ 1 ] = − t ∗ cos ( phi + pi / 3 ) ; s [ 2 ] = − t ∗ cos ( phi − pi / 3 ) ; num = 3 ; } e l s e { /∗ one r e a l s o l u t i o n ∗/ d = s q r t ( d ) ; double u = c b r t ( d−q ) , v = − c b r t ( d+q ) ; s [ 0 ] = u + v ; num = 1 ; } /∗ r e s u b s t i t u t e ∗/ sub = 1 . 0 / 3 ∗ A ; for ( i = 0 ; i <num; ++ i ) s [ i ] −= sub ; return num ; } 32 int S o l v e Q u a r t i c ( double c [ 5 ] , double s [ 4 ] ) { double e [ 4 ] , z , u , v , sub , A, B , C , d , sqa , p , q , r ; int i , num ; // x ˆ4 + Axˆ3 + Bxˆ2 + Cx + D = 0 A = c [3]/ c [ 4 ] ; B = c [2]/ c [ 4 ] ; C = c [1]/ c [ 4 ] ; d = c [0]/ c [4]; sqa = A ∗ A ; // x = y − A/ 4 => x ˆ4 + px ˆ2 + qx + r = 0 p = − 3 . 0 / 8 ∗ sqa + B ; q = 1 . 0 / 8 ∗ sqa ∗ A − 1 . 0 / 2 ∗ A ∗ B + C ; r = − 3.0/256∗ sqa ∗ sqa + 1 . 0 / 1 6 ∗ sqa ∗B − 1 . 0 / 4 ∗A∗C + d ; i f ( dcmp ( r ) = = 0 ) { // no a b s o l u t e term : y ( y ˆ3 + py + q ) = 0 e [0] = q ; e [1] = p ; e [2] = 0; e [3] = 1; num = S o l v e C u b i c ( e , s ) ; s [ num+ + ] = 0 ; } else { // s o l v e t h e r e s o l v e n t c u b i c . . . e [0] = 1.0/2 ∗ r ∗ p − 1.0/8 ∗ q ∗ q ; e [1] = − r ; e [2] = − 1.0/2 ∗ p ; e [3] = 1; SolveCubic ( e , s ) ; z = s [ 0 ]; // . . . and t a k e t h e one r e a l s o l u t i o n u = z ∗ z−r ; v = 2∗ z−p ; // . . . t o b u i l d two q u a d r i c e q u a t i o n s i f ( dcmp ( u)==0) u = 0 ; e l s e i f ( dcmp ( u ) >0) u=s q r t ( u ) ; e l s e return 0 ; i f ( dcmp ( v)==0) v = 0 ; e l s e i f ( dcmp ( v ) >0) v=s q r t ( v ) ; e l s e return 0 ; e [ 0 ] = z−u ; e [ 1 ] = dcmp ( q) <0 ? −v : v ; e [ 2 ] = 1 ; num = S o l v e Q u a d r i c ( e , s ) ; e [ 0 ] = z+u ; e [ 1 ] = dcmp ( q ) <0 ? v : − v ; e [ 2 ] = 1 ; num += S o l v e Q u a d r i c ( e , s + num ) ; } sub = 1 . 0 / 4 ∗A ; for ( i = 0 ; i <num; ++ i ) s [ i ] −= sub ; // r e s u b s t i t u t e return num ; } 4.7 Fast Fourier Transform const double e p s=1e −8; const double p i=a c o s ( − 1 . 0 ) ; #define cp complex<double> i n l i n e int max( int a , int b ) { i f ( a>b ) return a ; e l s e return b ; } i n l i n e int dcmp ( double a ) { i f ( a<−e p s ) return − 1 ; return ( a>e p s ) ; } void f f t ( cp ∗ x , int n , cp ∗ y , int bInv ) // y=Wx, w [ j , k ]= e ˆ i j k { i f ( n==1) { y [ 0 ] = x [ 0 ] ; return ; } cp ∗ xeven = new cp [ n / 2 ] , ∗ xodd = new cp [ n / 2 ] , w( 1 , 0 ) , ∗ yeven = new cp [ n / 2 ] , ∗ yodd = new cp [ n / 2 ] , wn ; int i ; i f ( bInv ) wn=cp ( c o s (−2∗ p i /n ) , s i n (−2∗ p i /n ) ) ; e l s e wn=cp ( c o s ( 2 ∗ p i /n ) , s i n ( 2 ∗ p i /n ) ) ; fo r ( i = 0 ; i <n / 2 ; i ++) { xeven [ i ] = x [ i ∗ 2 ] ; xodd [ i ] = x [ i ∗ 2 + 1 ] ; } f f t ( xeven , n / 2 , yeven , bInv ) ; f f t ( xodd , n / 2 , yodd , bInv ) ; fo r ( i = 0 ; i <n / 2 ; i ++) { y[ i ] = yeven [ i ] + w∗ yodd [ i ] ; y [ i+n / 2 ] = yeven [ i ] − w∗ yodd [ i ] ; w ∗= wn ; } delete xeven ; delete yeven ; delete xodd ; delete yodd ; } 33 4.8 FFT - Polynomial Multiplication void Po ly Mu lt i ( double ∗ a , int na , double ∗ b , int nb , double ∗ c , int &nc ) { int i , j , n=(na>nb ) ? na : nb ; n=1<<((int ) c e i l ( l o g ( 2 ∗ n ) / l o g (2) − e p s ) ) ; cp ∗ x=new cp [ n ] , ∗ ya=new cp [ n ] , ∗ yb=new cp [ n ] , ∗ yc=new cp [ n ] ; fo r ( i =0; i <n ; i ++) x [ i ]=( i <na ) ? a [ i ] : 0 ; f f t ( x , n , ya , 0 ) ; fo r ( i =0; i <n ; i ++) x [ i ]=( i <nb ) ? b [ i ] : 0 ; f f t ( x , n , yb , 0 ) ; fo r ( i =0; i <n ; i ++) yc [ i ]= ya [ i ] ∗ yb [ i ] ; f f t ( yc , n , x , 1 ) ; fo r ( i =0; i <n ; i ++) c [ i ]=x [ i ] . r e a l ( ) / n ; fo r ( nc=n ; nc >0 && dcmp ( c [ nc −1])==0; nc −−); delete x ; delete ya ; delete yb ; delete yc ; } 4.9 rk = FFT - Convolution Pn−1 i=0 a[i] ∗ b[i − k] void C o n v o l u t i o n 1 ( int ∗ a , int ∗ b , int ∗ c , int n ) { int m, i , j , ∗ rb=new int [ n ] ; rb [ 0 ] = b [ 0 ] ; fo r ( i =1; i <n ; i ++) rb [ i ]=b [ n−i ] ; Po l yMu lt i1 ( a , n , rb , n , c ,m) ; fo r ( i =0; i <n ; i ++) c [ i ]+=c [ i+n ] ; delete [ ] rb ; } \ \ N must be power o f 2 void C o n v o l u t i o n 2 ( int ∗ a , int ∗ b , int ∗ c , int n ) { int i , j ; cp ∗ x=new cp [ n ] , ∗ ya=new cp [ n ] , ∗ yb=new cp [ n ] , ∗ yc=new cp [ n ] ; x [0]=b [ 0 ] ; fo r ( i =1; i <n ; i ++) x [ i ]=( i <n ) ? b [ n−i ] : 0 ; f f t ( x , n , yb , 0 ) ; fo r ( i =0; i <n ; i ++) x [ i ]=( i <n ) ? a [ i ]:0; f f t ( x , n , ya , 0 ) ; fo r ( i =0; i <n ; i ++) yc [ i ]= ya [ i ] ∗ yb [ i ] ; f f t ( yc , n , x , 1 ) ; fo r ( i =0; i <n ; i ++) c [ i ]= int ( x [ i ] . r e a l ( ) / n + 0 . 5 ) ; delete x ; delete ya ; delete yb ; delete yc ; } 4.10 FFT - Reverse Bits #define f o r i f ( 0 ) ; e l s e f or const double p i = a c o s ( − 1 . 0 ) ; const int MFB = 1 6 ; int ∗ ∗ bt = 0 ; struct cp { double re , im ; } ; i n l i n e int R e v e r s e B i t s ( int index , int bitnum ) { int r e t = 0 ; fo r ( int i = 0 ; i <bitnum ; ++ i , i n d e x >>= 1) r e t = ( r e t < < 1) | ( index & 1 ) ; return r e t ; } 34 void InitFFT ( ) { bt = new int ∗ [MFB ] ; int i , j , l e n g t h ; fo r ( i =1 , l e n g t h = 2 ; i<=MFB; ++ i , l e n g t h <<=1) { bt [ i −1] = new int [ l e n g t h ] ; f o r ( j = 0 ; j <l e n g t h ; ++ j ) bt [ i − 1 ] [ j ] = R e v e r s e B i t s ( j , i ) ; } } i n l i n e int FRB( int i , int bitnum ) { return bitnum <= MFB ? bt [ bitnum − 1 ] [ i ] : R e v e r s e B i t s ( i , bitnum ) ; } void FFT( cp ∗ in , cp ∗ out , int n , bool bInv ) { int i , j , k , ed , l e n , bitnum = 0 ; i f ( ! bt ) InitFFT ( ) ; while ( !((1 < < bitnum)&n ) ) bitnum++; fo r ( i = 0 ; i <n; ++ i ) out [FRB( i , bitnum ) ] = i n [ i ] ; double b a s i c a n g l e = p i ∗ ( bInv ? − 2 : 2 ) ; cp a0 , a1 , a2 , a , b ; fo r ( ed = 1 , l e n = 2 ; l e n <= n ; l e n < <= 1) { double d e l t a a n g l e = b a s i c a n g l e / l e n ; double s i n 1 = s i n (− d e l t a a n g l e ) , s i n 2 = s i n (− d e l t a a n g l e ∗ 2 ) ; double c o s 1 = c o s (− d e l t a a n g l e ) , c o s 2 = c o s (− d e l t a a n g l e ∗ 2 ) ; f o r ( i = 0 ; i <n ; i+=l e n ) { a1 . r e=c o s 1 ; a1 . im=s i n 1 ; a2 . r e=c o s 2 ; a2 . im=s i n 2 ; f o r ( j=i , k = 0 ; k<ed ; ++ j , ++k ) { a0 . r e =2∗ c o s 1 ∗ a1 . re−a2 . r e ; a0 . im=2∗ c o s 1 ∗ a1 . im−a2 . im ; a2 = a1 ; a1 = a0 ; b=out [ j+ed ] ; a . r e = a0 . r e ∗b . r e − a0 . im∗b . im ; a . im = a0 . im∗b . r e + a0 . r e ∗b . im ; out [ j+ed ] . r e=out [ j ] . re−a . r e ; out [ j+ed ] . im=out [ j ] . im−a . im ; out [ j ] . r e+=a . r e ; out [ j ] . im+=a . im ; } } ed = l e n ; } i f ( bInv ) f or ( int i = 0 ; i < n; ++ i ) { out [ i ] . r e /= n ; out [ i ] . im/=n ; } } // n must be power o f 2 void c o n v o l u t i o n ( double ∗ a , double ∗ b , double ∗ r , int n ) { int i ; cp ∗ s=new cp [ n ] , ∗ d1=new cp [ n ] , ∗ d2=new cp [ n ] , ∗ y=new cp [ n ] ; s [ 0 ] . im=b [ 0 ] ; s [ 0 ] . r e =0; fo r ( i = 1 ; i <n; ++ i ) s [ i ] . r e=b [ n−i ] , s [ i ] . im = 0 ; FFT( s , d2 , n , f a l s e ) ; fo r ( i = 0 ; i <n; ++ i ) s [ i ] . r e=a [ i ] , s [ i ] . im = 0 ; FFT( s , d1 , n , f a l s e ) ; fo r ( i = 0 ; i <n; ++ i ) { y [ i ] . r e = d1 [ i ] . r e ∗d2 [ i ] . r e − d1 [ i ] . im∗d2 [ i ] . im ; y [ i ] . im = d1 [ i ] . r e ∗d2 [ i ] . im + d1 [ i ] . im∗d2 [ i ] . r e ; } FFT( y , s , n , true ) ; fo r ( i = 0 ; i <n; ++ i ) r [ i ] = s [ i ] . r e ; delete s ; delete d1 ; delete d2 ; delete y ; } 35 4.11 Linear Programming - Primal Simplex Primal Simplex Method for solving Linear Programming problem in Standard Form maximize c1 x1 + c2 x2 + · · · + cn xn + ans subject to a1,1 x1 + a1,2 x2 + · · · + a1,n xn ≤ rhs1 a2,1 x1 + a2,2 x2 + · · · + a2,n xn ≤ rhs2 .. . am,1 x1 + am,2 x2 + · · · + am,n xn ≤ rhsm const double e p s = 1 e −8; const double i n f = 1 e15 ; #define #define #define #define #define OPTIMAL −1 UNBOUNDED −2 FEASIBLE −3 INFEASIBLE −4 PIVOT OK 1 int b a s i c [ maxn ] , row [ maxm ] , c o l [ maxn ] ; double c0 [ maxn ] ; double dcmp ( double x ) { i f ( x > e p s ) return 1 ; i f ( x < − e p s ) return −1; return 0 ; } int P i v o t ( int n , int m, double ∗ c , double a [ maxn ] [ maxn ] , double ∗ rhs , int & i , int & j ) { double min = i n f ; int k = −1; fo r ( j = 0 ; j<=n ; j ++) i f ( ! b a s i c [ j ] && dcmp ( c [ j ] ) > 0 ) i f ( k < 0 | | dcmp ( c [ j ]− c [ k ] ) > 0 ) k=j ; j=k ; i f ( k < 0 ) return OPTIMAL; fo r ( k=−1, i = 1 ; i<=m; i ++) i f ( dcmp ( a [ i ] [ j ] ) > 0 ) i f ( dcmp ( r h s [ i ] / a [ i ] [ j ]−min ) < 0 ) { min = r h s [ i ] / a [ i ] [ j ] ; k=i ; } i=k ; i f ( k < 0 ) return UNBOUNDED; e l s e return PIVOT OK ; } int P h a s e I I ( int n , int m, double ∗ c , double a [ maxn ] [ maxn ] , double ∗ rhs , double &ans , int P i v o t I n d e x ) { int i , j , k , l ; double tmp ; while ( k=P i v o t ( n ,m, c , a , rhs , i , j ) , k==PIVOT OK | | P i v o t I n d e x ) { i f ( P i v o t I n d e x ) { j = 0 ; i=P i v o t I n d e x ; P i v o t I n d e x = 0 ; } b a s i c [ row [ i ] ] = 0 ; c o l [ row [ i ] ] = 0 ; b a s i c [ j ] = 1 ; c o l [ j ]= i ; row [ i ]= j ; tmp=a [ i ] [ j ] ; for ( k=0;k<=n ; k++) a [ i ] [ k]/=tmp ; r h s [ i ]/=tmp ; f o r ( k=1;k<=m; k++) i f ( k!= i && dcmp ( a [ k ] [ j ] ) ) { tmp = −a [ k ] [ j ] ; for ( l =0; l<=n ; l ++) a [ k ] [ l ]+=tmp∗ a [ i ] [ l ] ; r h s [ k ] += tmp∗ r h s [ i ] ; } tmp=−c [ j ] ; for ( l =0; l<=n ; l ++) c [ l ]+=a [ i ] [ l ] ∗ tmp ; ans−=tmp∗ r h s [ i ] ; } return k ; } 36 int PhaseI ( int n , int m, double ∗ c , double a [ maxn ] [ maxn ] , double ∗ rhs , double & ans ) { int i , j , k = −1; double tmp , min = 0 , ans0 = 0 ; fo r ( i = 1 ; i<=m; i ++) i f ( dcmp ( r h s [ i ]−min ) < 0 ) { min=r h s [ i ] ; k=i ; } i f ( k < 0 ) return FEASIBLE ; fo r ( i = 1 ; i<=m; i ++) a [ i ] [ 0 ] = − 1 ; fo r ( j = 1 ; j<=n ; j ++) c0 [ j ] = 0 ; c0 [ 0 ] = − 1 ; P h a s e I I ( n , m, c0 , a , rhs , ans0 , k ) ; i f ( dcmp ( ans0 ) < 0 ) return INFEASIBLE ; fo r ( i = 1 ; i<=m; i ++) a [ i ] [ 0 ] = 0 ; fo r ( j = 1 ; j<=n ; j ++) i f ( dcmp ( c [ j ] ) & & b a s i c [ j ] ) { tmp = c [ j ] ; ans += r h s [ c o l [ j ] ] ∗ tmp ; f o r ( i = 0 ; i<=n ; i ++) c [ i ] −= tmp∗ a [ c o l [ j ] ] [ i ] ; } return FEASIBLE ; } int s i m p l e x ( int n , int m, double ∗ c , double a [ maxn ] [ maxn ] , double ∗ rhs , double &ans , double ∗ x ) // s t a n d a r d form { int i , j , k ; fo r ( i = 1 ; i<=m; i ++) { f o r ( j=n + 1 ; j<=n+m; j ++) a [ i ] [ j ] = 0 ; a [ i ] [ n+i ] = 1 ; a [ i ] [ 0 ] = 0 ; row [ i ] = n+i ; c o l [ n+i ] = i ; } k = PhaseI ( n+m, m, c , a , rhs , ans ) ; i f ( k == INFEASIBLE ) return k ; k = P h a s e I I ( n+m, m, c , a , rhs , ans , 0 ) ; fo r ( j =0; j<=n+m; j ++) x [ j ] = 0 ; fo r ( i =1; i<=m; i ++) x [ row [ i ] ] = r h s [ i ] ; return k ; } int n , m; double c [ maxn ] , ans , a [ maxm ] [ maxn ] , r h s [ maxm ] , x [ maxn ] ; int main ( ) { ifstream cin (” lp . in ” ) ; int i , j ; while ( c i n >>n>>m && ! c i n . f a i l ( ) ) { f o r ( j = 1 ; j<=n ; j ++) c i n >>c [ j ] ; c i n >>ans ; f o r ( i = 1 ; i<=m; i ++){ for ( j = 1 ; j<=n ; j ++) switch ( s i m p l e x ( n , m, c , a , rhs , ans , x ) { case OPTIMAL : p r i n t f ( ”OPTIMAL\n%10 l f \n” , ans ) ; for ( j =1; j<=n ; j ++) p r i n t f ( ”x [ %2d break ; case UNBOUNDED : p r i n t f ( ”UNBOUNDED\n” ) ; break ; case INFEASIBLE : p r i n t f ( ”INFEASIBLE\n” ) ; break ; } p r i n t f ( ” \n” ) ; } return 0 ; } 37 c [0]=0; c i n >>a [ i ] [ j ] ; c i n >>r h s [ i ] ; } ) ] = %10 l f \n” , j , x [ j ] ) ; Chapter 5 Computational Geometry 5.1 Basic Operations const double e p s = 1 e −8; const double p i = a c o s ( − 1 . 0 ) ; struct CPoint { double x , y ; } ; double min ( double x , double y ) { i f ( x<y ) return x ; e l s e return y ; } double max( double x , double y ) { i f ( x>y ) return x ; e l s e return y ; } double s q r ( double x ) { return x∗x ; } int dcmp ( double x ) { i f ( x<−e p s ) return − 1 ; e l s e return ( x>e p s ) ; } double c r o s s ( CPoint p0 , CPoint p1 , CPoint p2 ) { return ( p1 . x−p0 . x ) ∗ ( p2 . y−p0 . y)−(p2 . x−p0 . x ) ∗ ( p1 . y−p0 . y ) ; } double dot ( CPoint p0 , CPoint p1 , CPoint p2 ) { return ( p1 . x−p0 . x ) ∗ ( p2 . x−p0 . x)+( p1 . y−p0 . y ) ∗ ( p2 . y−p0 . y ) ; } double d i s s q r ( CPoint p1 , CPoint p2 ) { return s q r ( p1 . x−p2 . x)+ s q r ( p1 . y−p2 . y ) ; } double d i s ( CPoint p1 , CPoint p2 ) { return s q r t ( s q r ( p1 . x−p2 . x)+ s q r ( p1 . y−p2 . y ) ) ; } int PointEqual ( const CPoint &p1 , const CPoint &p2 ) { return dcmp ( p1 . x−p2 . x)==0 && dcmp ( p1 . y−p2 . y)==0; } 38 5.2 Extended Operations // C r o s s i n g Angle o f P0P1 −> P0P2 , range i n ( − pi , p i ] double a n g l e ( CPoint p0 , CPoint p1 , CPoint p2 ) { double c r = c r o s s ( p0 , p1 , p2 ) ; double dt = dot ( p0 , p1 , p2 ) ; i f ( dcmp ( c r )==0) c r = 0 . 0 ; i f ( dcmp ( dt )==0) dt = 0 . 0 ; return atan2 ( cr , dt ) ; } int PointOnLine ( CPoint p0 , CPoint p1 , CPoint p2 ) { return dcmp ( c r o s s ( p0 , p1 , p2 ))==0; } int PointOnSegment ( CPoint p0 , CPoint p1 , CPoint p2 ) { return dcmp ( c r o s s ( p0 , p1 , p2))==0 && dcmp ( dot ( p0 , p1 , p2 )) <=0; } // 1 = c r o s s ; 0 = parallel ; −1 = o v e r l a p int L i n e I n t e r s e c t i o n ( CPoint p1 , CPoint p2 , CPoint p3 , CPoint p4 , CPoint &cp ) { double u=c r o s s ( p1 , p2 , p3 ) , v=c r o s s ( p2 , p1 , p4 ) ; i f ( dcmp ( u+v ) ) { cp . x=(p3 . x∗v + p4 . x∗u ) / ( v+u ) ; cp . y=(p3 . y∗v + p4 . y∗u ) / ( v+u ) ; return 1 ; } i f ( dcmp ( u ) ) return 0 ; // e l s e u=v =0; i f ( dcmp ( c r o s s ( p3 , p4 , p1 ) ) ) return 0 ; return −1; } int S e g m e n t I n t e r s e c t i o n ( CPoint p1 , CPoint p2 , CPoint p3 , CPoint p4 , CPoint &cp ) { int r e t=L i n e I n t e r s e c t i o n ( p1 , p2 , p3 , p4 , cp ) ; i f ( r e t ==1) return PointOnSegment ( cp , p1 , p2 ) && PointOnSegment ( cp , p3 , p4 ) ; i f ( r e t ==−1 && ( PointOnSegment ( p1 , p3 , p4 ) | | PointOnSegment ( p2 , p3 , p4 ) | | PointOnSegment ( p3 , p1 , p2 ) | | PointOnSegment ( p4 , p1 , p2 ) ) ) return −1; return 0 ; } int S e g m e n t I n t e r s e c T e s t ( CPoint p1 , CPoint p2 , CPoint p3 , CPoint p4 ) { i f ( max( p1 . x , p2 . x ) + e p s < min ( p3 . x , p4 . x ) | | max( p3 . x , p4 . x ) + e p s < min ( p1 . x , p2 . x ) | | max( p1 . y , p2 . y ) + e p s < min ( p3 . y , p4 . y ) | | max( p3 . y , p4 . y ) + e p s < min ( p1 . y , p2 . y ) ) return 0 ; int d1=dcmp ( c r o s s ( p3 , p4 , p2 ) ) ; int d2=dcmp ( c r o s s ( p3 , p4 , p1 ) ) ; int d3=dcmp ( c r o s s ( p1 , p2 , p4 ) ) ; int d4=dcmp ( c r o s s ( p1 , p2 , p3 ) ) ; i f ( d1∗d2 = = 1 | | d3∗d4 ==1 ) return 0 ; i f ( d1==0 && d2==0 && d3==0 && d4 ==0 ) return −1; return 1 ; } 39 // 0 = o u t s i d e ; 1 = inside ; 2 = boundary int P o i n t I n P o l y g o n ( CPoint cp , CPoint p [ ] , int n ) { int i , k , d1 , d2 , wn=0; double sum=0; p [ n]=p [ 0 ] ; fo r ( i =0; i <n ; i ++) { i f ( PointOnSegment ( cp , p [ i ] , p [ i + 1 ] ) ) return 2 ; k = dcmp ( c r o s s ( p [ i ] , p [ i +1] , cp ) ) ; d1 = dcmp ( p [ i + 0 ] . y − cp . y ) ; d2 = dcmp ( p [ i + 1 ] . y − cp . y ) ; i f ( k>0 && d1<=0 && d2 >0) wn++; i f ( k<0 && d2<=0 && d1 >0) wn−−; } return wn! = 0 ; } double PointToLine ( CPoint p0 , CPoint p1 , CPoint p2 , CPoint &cp ) { double d=d i s ( p1 , p2 ) ; double s = c r o s s ( p1 , p2 , p0 ) / d ; cp . x = p0 . x + s ∗ ( p2 . y−p1 . y ) / d ; cp . y = p0 . y − s ∗ ( p2 . x−p1 . x ) / d ; return s ; // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ S i g n e d Magnitude ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ } void P o i n t P r o j L i n e ( CPoint p0 , CPoint p1 , CPoint p2 , CPoint &cp ) { double t = dot ( p1 , p2 , p0 ) / dot ( p1 , p2 , p2 ) ; cp . x = p1 . x + t ∗ ( p2 . x−p1 . x ) ; cp . y = p1 . y + t ∗ ( p2 . y−p1 . y ) ; } 40 5.3 Convex Hull Graham Scan, O(N log N ) CPoint bp ; // f o r p o l a r s o r t i n g int PolarCmp ( const CPoint &p1 , const CPoint &p2 ) { int u=dcmp ( c r o s s ( bp , p1 , p2 ) ) ; return u > 0 | | ( u==0 && dcmp ( d i s s q r ( bp , p1)− d i s s q r ( bp , p2 ) ) < 0 ) ; } void GrahamScan ( CPoint p i n [ ] , int n , CPoint ch [ ] , int &m) { int i , j , k , u , v ; memcpy ( ch , pin , n∗ s i z e o f ( CPoint ) ) ; fo r ( i=k = 0 ; i <n ; i ++) { u = dcmp ( ch [ i ] . x − ch [ k ] . x ) ; v = dcmp ( ch [ i ] . y − ch [ k ] . y ) ; i f ( v < 0 | | ( v==0 && u < 0 ) ) k=i ; } bp = ch [ k ] ; s t d : : s o r t ( ch , ch+n , PolarCmp ) ; n = s t d : : unique ( ch , ch+n , PointEqual )−ch ; i f ( n <=1 ) { m = n ; return ; } i f ( dcmp ( c r o s s ( ch [ 0 ] , ch [ 1 ] , ch [ n −1]))==0 ) { m= 2 ; ch [ 1 ] = ch [ n − 1 ] ; return ; } ch [ n++]=ch [ 0 ] ; fo r ( i =1, j = 2 ; j <n ; j ++) { while ( i >0 && dcmp ( c r o s s ( ch [ i −1] , ch [ i ] , ch [ j ] ) ) < = 0 ) i −−; ch[++ i ] = ch [ j ] ; } m=i ; } void GrahamScanReserved ( CPoint p i n [ ] , int n , CPoint ch [ ] , int &m) { int i , j , k , u , v ; memcpy ( ch , pin , n∗ s i z e o f ( CPoint ) ) ; fo r ( i=k = 0 ; i <n ; i ++) { u = dcmp ( ch [ i ] . x − ch [ k ] . x ) ; v = dcmp ( ch [ i ] . y − ch [ k ] . y ) ; i f ( v < 0 | | ( v==0 && u < 0 ) ) k=i ; } bp = ch [ k ] ; s t d : : s o r t ( ch , ch+n , PolarCmp ) ; n = s t d : : unique ( ch , ch+n , PointEqual )−ch ; i f ( n>0 && dcmp ( c r o s s ( ch [ 0 ] , ch [ 1 ] , ch [ n − 1 ] ) ) ) { f o r ( i=n − 1 ; dcmp ( c r o s s ( ch [ 0 ] , ch [ n −1] , ch [ i ] ) ) = = 0 ; i −−); s t d : : r e v e r s e ( ch+i +1, ch+n ) ; } fo r (m=0, i = 0 ; i <n ; i ++) { while ( m>=2 && dcmp ( c r o s s ( ch [m−2] , ch [m−1] , ch [ i ] ) ) < 0 ) m−−; ch [m++] = ch [ i ] ; } } 41 Montone Chain, O(N log N ) int VerticalCmp ( const CPoint &p1 , const CPoint &p2 ) { return p1 . y+eps<p2 . y | | ( p1 . y<p2 . y+e p s && p1 . x+eps<p2 . x ) ; } void MontoneChain ( CPoint p i n [ ] , int n , CPoint ch [ ] , int &m) { int i , k ; CPoint ∗ p = new CPoint [ n ] ; memcpy ( p , pin , n∗ s i z e o f ( CPoint ) ) ; s t d : : s o r t ( p , p+n , VerticalCmp ) ; n = s t d : : unique ( p , p+n , PointEqual )−p ; fo r ( m=i = 0 ; i <n ; i ++ ) { while ( m>1 && dcmp ( c r o s s ( ch [m−2] , ch [m−1] , p [ i ] ) ) < = 0 ) m−−; ch [m++]=p [ i ] ; } k=m; fo r ( i=n − 2 ; i >=0; i −− ) { while ( m>k && dcmp ( c r o s s ( ch [m−2] , ch [m−1] , p [ i ] ) ) < = 0 ) m−−; ch [m++]=p [ i ] ; } i f ( n >1) m−−; delete p ; } void MontoneChainReserved ( CPoint p i n [ ] , int n , CPoint ch [ ] , int &m) { int i , k ; CPoint ∗ p = new CPoint [ n ] ; memcpy( p , pin , n∗ s i z e o f ( CPoint ) ) ; s t d : : s o r t ( p , p+n , VerticalCmp ) ; n = s t d : : unique ( p , p+n , PointEqual )−p ; fo r ( m=i = 0 ; i <n ; i ++ ) { while ( m>1 && dcmp ( c r o s s ( ch [m−2] , ch [m−1] , p [ i ] ) ) < 0 ) m−−; ch [m++]=p [ i ] ; } i f ( n==m ) return ; k=m; fo r ( i=n − 2 ; i >=0; i −− ) { while ( m>k && dcmp ( c r o s s ( ch [m−2] , ch [m−1] , p [ i ] ) ) < 0 ) m−−; ch [m++]=p [ i ] ; } i f ( n >1) m−−; delete p ; } 42 Javis March, O(N H) int ConvexJavisMarchCmp ( CPoint p0 , CPoint p1 , CPoint pnew ) { int u=dcmp ( c r o s s ( p0 , p1 , pnew ) ) ; return ( u < 0 | | ( u==0 && dcmp ( d i s s q r ( pnew , p0)− d i s s q r ( p1 , p0 ) ) > 0 ) ) ; } void ConvexJavisMarch ( CPoint p i n [ ] , int n , CPoint ch [ ] , int &m) { int i , j , k , u , v ; char ∗mk = new char [ n ] ; CPoint ∗ p = new CPoint [ n ] ; memcpy ( p , pin , n∗ s i z e o f ( CPoint ) ) ; memset (mk, 0 , n ) ; fo r ( i=k=0; i <n ; i ++) { u=dcmp ( p [ i ] . x−p [ k ] . x ) ; v=dcmp ( p [ i ] . y−p [ k ] . y ) ; i f ( v < 0 | | ( v==0 && u < 0 ) ) k=i ; } fo r (m= 0 ; !mk [ k ] ; m++) { mk [ k ] = 1 ; ch [m]=p [ k ] ; f o r ( j=k=0; j <n ; j ++) i f ( ConvexJavisMarchCmp ( ch [m] , p [ k ] , p [ j ] ) ) k=j ; } delete p ; delete mk ; } 5.4 Point Set Diameter P must be convex in ccw order and no trhee points on an edge and will be changed after computing it’s convex hull double Diameter ( CPoint ∗ p , int n ) { Convex ( p , n , p , n ) ; i f ( n==1 ) return 0 ; i f ( n==2 ) return d i s ( p [ 0 ] , p [ 1 ] ) ; int u , nu , v , nv , k ; double r e t = 0 ; p[n] = p [ 0 ] ; fo r ( u=0,v = 1 ; u<n ; u=nu ) { nu = u+1; while ( 1 ) { nv = ( v+1)%n ; k = dcmp ( ( p [ nu ] . x−p [ u ] . x ) ∗ ( p [ nv ] . y−p [ v ] . y ) − (p [ nv ] . x−p [ v ] . x ) ∗ ( p [ nu ] . y−p [ u ] . y ) ) ; i f ( k <=0 ) break ; v=nv ; } r e t = max ( r e t , d i s ( p [ u ] , p [ v ] ) ) ; i f ( k ==0 ) r e t = max ( r e t , d i s ( p [ u ] , p [ nv ] ) ) ; } return r e t ; } 43 5.5 Closest Pair #define s q r ( z ) ( ( z ) ∗ ( z ) ) struct p o i n t { double x , y ; } pt [ maxn ] ; // [ 1 . . n ] int n , o [ maxn ] , on ; int dcmp ( double a , double b ) { i f ( a − b < 1 e −10 && b − a < 1 e −10) return 0 ; i f ( a > b ) return 1 ; return −1; } bool cmp( const p o i n t & a , const p o i n t & b ) { return dcmp ( a . x , b . x ) < 0 ; } bool cmp2 ( const int & a , const int & b ) { return dcmp ( pt [ a ] . y , pt [ b ] . y ) < 0 ; } double d i s ( p o i n t a , p o i n t b ) { return s q r t ( s q r ( a . x − b . x ) + s q r ( a . y − b . y ) ) ; } double min ( double a , double b ) { return a < b ? a : b ; } double s e a r c h ( int s , int t ) { int mid = ( s + t ) / 2 , i , j ; double r e t ( 1 e300 ) ; i f ( s >= t ) return r e t ; fo r ( i=mid ; i>=s && !dcmp ( pt [ i ] . x , pt [ mid ] . x ) ; i − −); r e t=s e a r c h ( s , i ) ; fo r ( i=mid ; i<=t && !dcmp ( pt [ i ] . x , pt [ mid ] . x ) ; i ++); r e t=min ( r e t , s e a r c h ( i , t ) ) ; on =0; fo r ( i=mid ; i>=s && dcmp ( pt [ mid ] . x−pt [ i ] . x , r e t ) <=0; i −−) o[++on]= i ; fo r ( i=mid + 1 ; i<=t && dcmp ( pt [ i ] . x−pt [ mid ] . x , r e t ) <= 0; i ++) o[++on]= i ; s t d : : s o r t ( o+1,o+on+1,cmp2 ) ; fo r ( i = 1 ; i<=on ; i ++) for ( j = 1 ; j <=10; j ++) i f ( i+j<=on ) r e t = min ( r e t , d i s ( pt [ o [ i ] ] , pt [ o [ i+j ] ] ) ) ; return r e t ; } double s o l v e ( ) { s t d : : s o r t ( pt +1, pt+1+n , cmp ) ; return s e a r c h ( 1 , n ) ; } 5.6 Circles Crossing of |P − P0 | = r and ax + by + c = 0 int C i r c l e C r o s s L i n e 1 ( CPoint p0 , double r , double a , double b , double c , CPoint &cp1 , CPoint & cp2 ) { double aa = a ∗ a , bb = b ∗ b , s = aa + bb ; double d = r ∗ r ∗ s − s q r ( a ∗p0 . x+b∗p0 . y+c ) ; i f ( d+eps < 0 ) return 0 ; i f ( d<e p s ) d = 0 ; e l s e d = s q r t ( d ) ; double ab = a ∗ b , bd = b ∗ d , ad = a ∗ d ; double xx = bb ∗ p0 . x − ab ∗ p0 . y − a ∗ c ; double yy = aa ∗ p0 . y − ab ∗ p0 . x − b ∗ c ; cp2 . x = ( xx + bd ) / s ; cp2 . y = ( yy − ad ) / s ; cp1 . x = ( xx − bd ) / s ; cp1 . y = ( yy + ad ) / s ; i f ( d>e p s ) return 2 ; e l s e return 1 ; } 44 −−→ Crossing of |P − P0 | = r and P1 P2 int C i r c l e C r o s s L i n e 2 ( CPoint p0 , double r , CPoint p1 , CPoint p2 , CPoint &cp1 , CPoint & cp2 ) { double d , d12 , dx , dy ; d = f a b s ( PointToLine ( p0 , p1 , p2 , cp1 ) ) ; i f ( dcmp ( d−r ) > 0 ) return 0 ; i f ( dcmp ( d−r ) = = 0 ) { cp2 = cp1 ; return 1 ; } d = s q r t ( r ∗ r − d∗d ) / d i s ( p1 , p2 ) ; dx = ( p2 . x − p1 . x ) ∗ d ; dy = ( p2 . y − p1 . y ) ∗ d ; cp2 . x = cp1 . x + dx ; cp2 . y = cp1 . y + dy ; cp1 . x = cp1 . x − dx ; cp1 . y = cp1 . y − dy ; return 2 ; } Crossing of |P − P1 | = r1 and |P − P2 | = r2 int C i r c l e C r o s s C i r c l e 1 ( CPoint p1 , double r1 , CPoint p2 , double r2 , CPoint &cp1 , CPoint & cp2 ) { double mx = p2 . x−p1 . x , sx = p2 . x+p1 . x , mx2 = mx∗mx ; double my = p2 . y−p1 . y , sy = p2 . y+p1 . y , my2 = my∗my ; double sq = mx2 + my2 , d = −( sq−s q r ( r1−r 2 ) ) ∗ ( sq−s q r ( r 1+r 2 ) ) ; i f ( d+eps < 0 ) return 0 ; i f ( d<e p s ) d = 0 ; e l s e d = s q r t ( d ) ; double x = mx ∗ ( ( r 1+r 2 ) ∗ ( r1−r 2 ) + mx∗ sx ) + sx ∗my2 ; double y = my ∗ ( ( r 1+r 2 ) ∗ ( r1−r 2 ) + my∗ sy ) + sy ∗mx2 ; double dx = mx∗d , dy = my∗d ; sq ∗ = 2 ; cp1 . x = ( x − dy ) / sq ; cp1 . y = ( y + dx ) / sq ; cp2 . x = ( x + dy ) / sq ; cp2 . y = ( y − dx ) / sq ; i f ( d>e p s ) return 2 ; e l s e return 1 ; } Crossing of |P − P1 | = r1 and |P − P2 | = r2 int C i r c l e C r o s s C i r c l e 2 ( CPoint p1 , double r1 , CPoint p2 , double r2 , CPoint &cp1 , CPoint & cp2 ) { double a , b , c ; CommonAxis ( p1 , r1 , p2 , r2 , a , b , c ) ; return C i r c l e C r o s s L i n e 1 ( p1 , r1 , a , b , c , cp1 , cp2 ) ; } Common Axis of |P − P1 | = r1 and |P − P2 | = r2 of the ax + by + c = 0 form void CommonAxis ( CPoint p1 , double r1 , CPoint p2 , double r2 , double &a , double &b , double & c ) { double sx = p2 . x + p1 . x , mx = p2 . x − p1 . x ; double sy = p2 . y + p1 . y , my = p2 . y − p1 . y ; a = 2∗mx ; b = 2∗my ; c = − sx ∗mx − sy ∗my − ( r 1+r 2 ) ∗ ( r1−r 2 ) ; } 45 5.7 Largest Empty Convex Polygon #define ABS( x ) #define CROSS( x1 , y1 , x2 , y2 ) ( ( x ) >=0 ? ( x ) : − ( x ) ) ( ( x1 ) ∗ ( y2 )−( x2 ) ∗ ( y1 ) ) const double e p s = 1 e −8; struct CPoint { int x , y ; } ; int n ; CPoint p [ maxn ] ; double ans ; bool cmp( const CPoint &a , const CPoint &b ) { int v = CROSS ( a . x , a . y , b . x , b . y ) ; i f ( v > 0 ) return true ; i f ( v < 0 ) return f a l s e ; return ( a . x∗ a . x + a . y∗a . y < b . x∗b . x + b . y∗b . y ) ; } CPoint c [ maxn ] ; int nc ; double fm [ maxn ] [ maxn ] ; void sweep ( int x , int y ) { int i , j , k , m; double v , b e s t = 0 ; fo r ( nc=i = 0 ; i <n; ++ i ) i f ( p [ i ] . y<y | | p [ i ] . y==y && p [ i ] . x<x ) { c [ nc ] . x=p [ i ] . x−x ; c [ nc ++].y=p [ i ] . y−y ; } i f ( nc < 2 ) return ; s t d : : s o r t ( c , c + nc , cmp ) ; memset ( fm , 0 , s i z e o f ( fm ) ) ; fo r ( i = 1 ; i <nc ; ++ i ) { j=i − 1 ; while ( j >=0 && CROSS( c [ i ] . x , c [ i ] . y , c [ j ] . x , c [ j ] . y)==0) −− j ; int nev = 0 , ev [ maxn ] ; while ( j >=0 ) { v = CROSS( c [ j ] . x , c [ j ] . y , c [ i ] . x , c [ i ] . y ) / 2 . 0 ; k=j −1; while ( k>=0 && CROSS ( c [ j ] . x−c [ i ] . x , c [ j ] . y−c [ i ] . y , c [ k ] . x−c [ i ] . x , c [ k ] . y−c [ i ] . y ) >0 ) − − k ; i f ( k >=0 ) v += fm [ j ] [ k ] ; i f ( v−b e s t >e p s ) b e s t = v ; i f ( CROSS( c [ i ] . x , c [ i ] . y , c [ i − 1 ] . x , c [ i − 1 ] . y ) ) i f ( v−fm [ i ] [ j ]> e p s ) fm [ i ] [ j ]=v ; ev [ nev++ ]= j ; j=k ; } i f ( CROSS( c [ i ] . x , c [ i ] . y , c [ i − 1 ] . x , c [ i − 1 ] . y ) ) f o r ( j=nev − 2 ; j >=0; −− j ) i f ( fm [ i ] [ ev [ j +1]] −fm [ i ] [ ev [ j ]] > e p s ) fm [ i ] [ ev [ j ] ] = fm [ i ] [ ev [ j + 1 ] ] ; } i f ( b e s t −ans>e p s ) ans = b e s t ; } void main ( ) { int t , i ; f or ( s c a n f ( ”%d” , & t ) ; t ; −− t ) { s c a n f ( ”%d” , & n ) ; f o r ( i = 0 ; i <n; ++ i ) s c a n f ( ”%d %d” , & p [ i ] . x , & p [ i ] . y ) ; f o r ( ans=i = 0 ; i <n; ++ i ) sweep ( p [ i ] . x , p [ i ] . y ) ; // main p r o c e d u r e p r i n t f ( ”%.1 l f \n” , ans ) ; } } 46 5.8 Triangle Centers // INPUT : ( 2 4 2 , 8 9 ) , ( 2 1 2 , 1 8 5 ) , ( 7 1 , 1 2 8 ) , OUTPUT: ( 1 5 8 . 0 8 8 5 , 1 1 5 . 4 6 5 2 ) void C i r c u m c e n t e r ( CPoint p0 , CPoint p1 , CPoint p2 , CPoint &cp ) { double a1=p1 . x−p0 . x , b1=p1 . y−p0 . y , c1=( s q r ( a1)+ s q r ( b1 ) ) / 2 ; double a2=p2 . x−p0 . x , b2=p2 . y−p0 . y , c2=( s q r ( a2)+ s q r ( b2 ) ) / 2 ; double d = a1 ∗ b2 − a2 ∗ b1 ; cp . x = p0 . x + ( c1 ∗b2 − c2 ∗b1 ) / d ; cp . y = p0 . y + ( a1 ∗ c2 − a2 ∗ c1 ) / d ; } // INPUT : ( 2 4 2 , 8 9 ) , ( 2 1 2 , 1 8 5 ) , ( 7 1 , 1 2 8 ) , OUTPUT: ( 1 8 9 . 5 2 8 6 , 1 3 7 . 4 9 8 7 ) double I n c e n t e r ( CPoint A, CPoint B , CPoint C , CPoint &cp ) { double s , p , r , a , b , c ; a = d i s (B , C) , b = d i s (C , A) , c = d i s (A, B ) ; p = ( a + b + c ) / 2 ; s = s q r t ( p ∗ ( p−a ) ∗ ( p−b ) ∗ ( p−c ) ) ; r = s / p; cp . x = ( a ∗A. x + b∗B . x + c ∗C. x ) / ( a + b + c ) ; cp . y = ( a ∗A. y + b∗B . y + c ∗C. y ) / ( a + b + c ) ; return r ; } // INPUT : ( 2 4 2 , 8 9 ) , ( 2 1 2 , 1 8 5 ) , ( 7 1 , 1 2 8 ) , OUTPUT: ( 2 0 8 . 8 2 2 9 , 1 7 1 . 0 6 9 7 ) void O r t h o c e n t e r ( CPoint A, CPoint B , CPoint C , CPoint &cp ) { C i r c u m c e n t e r (A, B , C , cp ) ; cp . x = A. x + B . x + C. x − 2 ∗ cp . x ; cp . y = A. y + B . y + C. y − 2 ∗ cp . y ; } Find three numbers r, s, t which make P = rA + sB + tC and r + s + t = 1 void P a r a m e t r i c ( CPoint P , CPoint A , CPoint B , CPoint C , double &r , double &s , double & t ) { double d ; d = c r o s s ( A, B , C ) ; r = c r o s s ( P , B, C) / d ; s = c r o s s ( A, P , C ) / d ; t = c r o s s ( A, B , P ) / d ; } void P o l y g o n C e n t r o i d s ( CPoint p [ ] , int n , CPoint &cp ) { double sum=0 , s = 0 ; cp . x = 0 ; cp . y=0; fo r ( int i = 1 ; i <n − 1 ; i ++,sum+=s ) { s= cross ( p [ 0 ] , p [ i ] , p [ i +1] ); cp . x += s ∗ ( p [ 0 ] . x + p [ i ] . x + p [ i + 1 ] . x ) ; cp . y += s ∗ ( p [ 0 ] . y + p [ i ] . y + p [ i + 1 ] . y ) ; } cp . x/=sum ∗ 3 ; cp . y/=sum ∗ 3 ; } 47 5.9 Polyhedron Volume Remark : All faces are assumed oriented counterclockwise from the outside; Volume6 returns six times the volume of the tetrahedron determined by abc and the origin d. Volume6 is positive iff d is on the negative side of abc, where the positive side is determined by the rh-rule. So the volume is positive if the ccw normal to abc points outside the tetrahedron. struct TPoint { double x , y , z ; } ; typedef int TFace [ 3 ] ; double Volume6 ( TPoint a , TPoint b , TPoint c , TPoint d ) // d = o r i g i n { double vol , bdx , bdy , bdz , cdx , cdy , cdz ; bdx = b . x−d . x ; bdy = b . y−d . y ; bdz = b . z−d . z ; cdx = c . x−d . x ; cdy = c . y−d . y ; cdz = c . z−d . z ; v o l = ( a . z − d . z ) ∗ ( bdx ∗ cdy − bdy ∗ cdx ) + ( a . y − d . y ) ∗ ( bdz ∗ cdx − bdx ∗ cdz ) + ( a . x − d . x ) ∗ ( bdy ∗ cdz − bdz ∗ cdy ) ; return v o l ; } void main ( ) { int n , F , i , j ; double v o l ; TPoint p [ maxn ] ; TFace f a c e [ maxn∗2 −4]; c i n >>n ; f o r ( i = 0 ; i <n ; i ++) c i n >> p [ i ] . x >> p [ i ] . y >> p [ i ] . z ; c i n >>F ; f o r ( i = 0 ; i <F ; i ++) for ( j =0; j <3; j ++) c i n >> f a c e [ i ] [ j ] ; i f ( F ! = 2 ∗ n − 4 ) { p r i n t f ( ”Not a s i m p l e p o l y h e d r o n ! \ n” ) ; return ; } for ( v o l = i = 0 ; i < F ; i ++ ) v o l += Volume6 ( p [ f a c e [ i ] [ 0 ] ] , p [ f a c e [ i ] [ 1 ] ] , p [ f a c e [ i ] [ 2 ] ] , p [ 0 ] ) ; v o l / = 6 . 0 ; c o u t << v o l <<e n d l ; } 48 5.10 Planar Graph Contour int x [ maxn ] , y [ maxn ] , g [ maxn ] [ maxn ] , num [ maxn ] , base , n , s i z e , mk [ maxn ] [ maxn ] ; int s [ maxn ] , used [ maxn ] , ans ; double a n g l e [ maxn ] ; bool cmp( const int & i , const int&j ) { return a n g l e [ i ] < a n g l e [ j ] ; } void d f s ( int d , int u , int v ) { int i , j ,w ; s [ d ] = u ; used [ u]++; i f ( mk [ u ] [ v ] ) { i f ( d==s i z e ) { used [ u]−−; f o r ( j =1; j<=n ; j ++) i f ( used [ j ] > 1 ) break ; i f ( j<=n ) return ; i f ( j >n) ++ ans ; } return ; } mk [ u ] [ v ] = 1 ; fo r ( j = 0 ; j <num [ v ] ; j ++) i f ( g [ v ] [ j ]==u ) break ; j = ( j +1)%num [ v ] ; w = g [ v ] [ j ] ; d f s ( d +1 , v , w ) ; } void s o l v e ( ) { int i , j , k , l , u , v ; fo r ( i = 1 ; i<=n ; i ++){ b a s e=i ; f o r ( j = 1 ; j<=n ; j ++) a n g l e [ j ] = atan2 ( y [ j ]−y [ i ] , x [ j ]−x [ i ] ) ; s t d : : s o r t ( g [ i ] , g [ i ]+num [ i ] , cmp ) ; } u = 1 ; memset (mk , 0 , s i z e o f (mk ) ) ; fo r ( i = 2 ; i<=n ; i ++) i f ( y [ i ]<y [ u ] | | ( y [ i ]==y [ u ] && x [ i ]<x [ u ] ) ) u=i ; fo r ( v=−1, i = 0 ; i <num [ u ] ; i ++) { j = g [ u ] [ i ] ; i f ( j==u | | j==v ) continue ; i f ( v < 0 ) { v=j ; continue ; } k = ( x [ j ]−x [ u ] ) ∗ ( y [ v]−y [ u ]) −( y [ j ]−y [ u ] ) ∗ ( x [ v]−x [ u ] ) ; i f ( k < 0 ) v=j ; e l s e i f ( k ==0 ) i f ( y [ j ]<y [ v ] | | ( y [ j ]==y [ v ] && x [ j ]<x [ v ] ) ) v=j ; } d f s ( 0 , v , u ) ; ans = 0 ; // o u t e r c o n t o u r fo r ( i = 1 ; i<=n ; i ++) for ( j = 0 ; j <num [ i ] ; j ++) i f ( ! mk [ i ] [ g [ i ] [ j ] ] ) { memset ( used , 0 , s i z e o f ( used ) ) ; dfs (0 , i , g [ i ] [ j ] ) ; } } int main ( ) { int t , i , j , k , l ; c i n >>t ; while ( t −−>0) { c i n >>n ; f o r ( k = 0 ; k<n ; k++) { c i n >>i ; c i n >>x [ i ]>>y [ i ] ; c i n >>num [ i ] ; f o r ( j =0; j <num [ i ] ; j ++) c i n >>g [ i ] [ j ] ; } c i n >>s i z e ; ans = 0 ; i f ( s i z e <3) s i z e =3; s o l v e ( ) ; cout<<ans<<e n d l ; } return 0 ; } 49 5.11 Rectangles Area struct TSegNode { TSegNode ( int x , int y ) : L( x ) ,R( y ) , Lch ( −1) ,Rch( −1) , count ( 0 ) , l e n ( 0 ) { } TSegNode ( ) { TSegNode ( −1 , −1);} int L , R , Lch , Rch , count , l e n ; }; struct Tevent { int L , R , x ; bool s t y l e ; friend const bool operator < ( Tevent a , Tevent b ) { return a . x<b . x ; } }; int n l i s t , l i s t [MAXN∗ 4 ] , t o t a l , n , nevent ; TSegNode node [MAXN∗ 4 ] ; Tevent e v e n t [MAXN∗ 4 ] ; void C r e a t e T r e e ( int r ) { i f ( node [ r ] . R−node [ r ] . L> 1 ) { int mid = ( node [ r ] . L+node [ r ] . R)>>1; node [ t o t a l ] = TSegNode ( node [ r ] . L , mid ) ; node [ r ] . Lch = t o t a l ; C re a te T r e e ( t o t a l ++); node [ t o t a l ] = TSegNode ( mid , node [ r ] . R ) ; node [ r ] . Rch = t o t a l ; C re a te T r e e ( t o t a l ++); } } void Update ( int r , int L , int R , int v ) { i f ( L>=node [ r ] . R | | R<=node [ r ] . L ) return ; i f ( L<=node [ r ] . L && R>=node [ r ] . R ) { node [ r ] . count+=v ; i f ( v>0 && v==node [ r ] . count ) node [ r ] . l e n = node [ r ] . R−node [ r ] . L ; i f ( v<0 && node [ r ] . count ==0 ) i f ( node [ r ] . Lch < 0 ) node [ r ] . l e n = 0 ; e l s e node [ r ] . l e n = node [ node [ r ] . Lch ] . l e n + node [ node [ r ] . Rch ] . l e n ; } else { Update ( node [ r ] . Lch , L , R , v ) ; Update ( node [ r ] . Rch , L , R , v ) ; i f ( node [ r ] . count ==0 ) node [ r ] . l e n = node [ node [ r ] . Lch ] . l e n + node [ node [ r ] . Rch ] . l e n ; } } 50 int main ( ) { int i , j , r e s , l a s t ; s c a n f ( ”%d” , & n ) ; nevent = 0 ; n l i s t =0; fo r ( i = 0 ; i <n; ++ i ) { int lx , ly , ux , uy ; s c a n f ( ”%d %d %d %d” , & lx , & ly , & ux , & uy ) ; i f ( lx <ux && ly <uy ) { e v e n t [ nevent ] . x = l x ; e v e n t [ nevent ] . L = l y ; e v e n t [ nevent ] . R = uy ; e v e n t [ nevent ++]. s t y l e = true ; e v e n t [ nevent ] . x = ux ; e v e n t [ nevent ] . L = l y ; e v e n t [ nevent ] . R = uy ; e v e n t [ nevent ++]. s t y l e = f a l s e ; } l i s t [ n l i s t ++] = l y ; l i s t [ n l i s t ++] = uy ; } s t d : : s o r t ( event , e v e n t+nevent ) ; s t d : : s o r t ( l i s t , l i s t +n l i s t ) ; n l i s t = s t d : : unique ( l i s t , l i s t +n l i s t )− l i s t ; node [ t o t a l =0 , t o t a l ++] = TSegNode ( 0 , n l i s t −1); CreateTree ( 0 ) ; fo r ( i = 0 ; i <t o t a l ; ++ i ) { node [ i ] . L = l i s t [ node [ i ] . L ] ; node [ i ] . R = l i s t [ node [ i ] . R ] ; } res = i = 0; while ( i <nevent ) { f o r ( l a s t=e v e n t [ i ] . x ; e v e n t [ i ] . x==l a s t ; ++ i ) Update ( 0 , e v e n t [ i ] . L , e v e n t [ i ] . R , e v e n t [ i ] . s t y l e ? 1 : − 1 ) ; i f ( i < nevent ) r e s += ( e v e n t [ i ] . x − l a s t ) ∗ node [ 0 ] . l e n ; } p r i n t f ( ”%d\n” , r e s ) ; return 0 ; } 51 5.12 Rectangles Perimeter #define ABS( x ) ( ( x ) >=0 ? ( x ) : − ( x ) ) struct TSegNode { TSegNode ( int x , int y ) : L( x ) ,R( y ) , Lch ( −1) ,Rch( −1) , count ( 0 ) , l e n ( 0 ) { } TSegNode ( ) { TSegNode ( −1 , −1);} int L , R , Lch , Rch , count , l e n ; }; struct Tevent { int L , R , x ; bool s t y l e ; friend const bool operator < ( Tevent a , Tevent b ) { i f ( a . x!=b . x ) return a . x<b . x ; return ( a . s t y l e && ! b . s t y l e ) ; } }; int n , l x [MAXN] , l y [MAXN] , ux [MAXN] , uy [MAXN] , t o t a l , nevent , r e s ; TSegNode node [MAXN∗ 4 ] ; Tevent e v e n t [MAXN∗ 4 ] ; void C r e a t e T r e e ( int r ) { i f ( node [ r ] . R−node [ r ] . L> 1 ) { int mid = ( node [ r ] . L+node [ r ] . R)>>1; node [ t o t a l ] = TSegNode ( node [ r ] . L , mid ) ; node [ r ] . Lch = t o t a l ; C re a te T r e e ( t o t a l ++); node [ t o t a l ] = TSegNode ( mid , node [ r ] . R ) ; node [ r ] . Rch = t o t a l ; C re a te T r e e ( t o t a l ++); } } void Update ( int r , int L , int R , int v ) { i f ( L>=node [ r ] . R | | R<=node [ r ] . L ) return ; i f ( L<=node [ r ] . L && R>=node [ r ] . R ) { node [ r ] . count+=v ; i f ( v>0 && v==node [ r ] . count ) node [ r ] . l e n = node [ r ] . R−node [ r ] . L ; i f ( v<0 && node [ r ] . count ==0 ) i f ( node [ r ] . Lch < 0 ) node [ r ] . l e n = 0 ; e l s e node [ r ] . l e n = node [ node [ r ] . Lch ] . l e n + node [ node [ r ] . Rch ] . l e n ; } else { Update ( node [ r ] . Lch , L , R , v ) ; Update ( node [ r ] . Rch , L , R , v ) ; i f ( node [ r ] . count ==0 ) node [ r ] . l e n = node [ node [ r ] . Lch ] . l e n + node [ node [ r ] . Rch ] . l e n ; } } 52 void p r o c e s s ( ) { int n l i s t , l i s t [MAXN∗ 2 ] , l a s t , i , now ; nevent = 0 ; n l i s t = 0 ; fo r ( i = 0 ; i <n; ++ i ) { e v e n t [ nevent ] . x = l x [ i ] ; e v e n t [ nevent ] . L = ly [ i ] ; e v e n t [ nevent ] . R = uy [ i ] ; e v e n t [ nevent ++]. s t y l e = true ; e v e n t [ nevent ] . x = ux [ i ] ; e v e n t [ nevent ] . L = ly [ i ] ; e v e n t [ nevent ] . R = uy [ i ] ; e v e n t [ nevent ++]. s t y l e = f a l s e ; l i s t [ n l i s t ++] = ly [ i ] ; l i s t [ n l i s t ++] = uy [ i ] ; } s t d : : s o r t ( event , e v e n t+nevent ) ; s t d : : s o r t ( l i s t , l i s t +n l i s t ) ; n l i s t = int ( s t d : : unique ( l i s t , l i s t +n l i s t )− l i s t ) ; node [ t o t a l =0 , t o t a l ++] = TSegNode ( 0 , n l i s t −1); CreateTree ( 0 ) ; fo r ( i = 0 ; i <t o t a l ; ++ i ) { node [ i ] . L = l i s t [ node [ i ] . L ] ; node [ i ] . R = l i s t [ node [ i ] . R ] ; } las t = i = 0; while ( i <nevent ) { now = e v e n t [ i ] . x ; while ( i <nevent && e v e n t [ i ] . x==now && e v e n t [ i ] . s t y l e ) { Update ( 0 , e v e n t [ i ] . L , e v e n t [ i ] . R, 1 ) ; + + i ; } r e s += ABS( node [ 0 ] . l e n −l a s t ) ; l a s t = node [ 0 ] . l e n ; while ( i <nevent && e v e n t [ i ] . x==now ) { Update ( 0 , e v e n t [ i ] . L , e v e n t [ i ] . R, −1); ++ i ; } r e s += ABS( node [ 0 ] . l e n −l a s t ) ; l a s t = node [ 0 ] . l e n ; } } int main ( ) { int i ; s c a n f ( ”%d” , & n ) ; fo r ( i = 0 ; i <n; ++ i ) s c a n f ( ”%d %d %d %d” ,& l x [ i ] ,& l y [ i ] ,& ux [ i ] ,& uy [ i ] ) ; r e s =0; p r o c e s s ( ) ; fo r ( i = 0 ; i <n; ++ i ) { s t d : : swap ( l x [ i ] , l y [ i ] ) ; s t d : : swap ( ux [ i ] , uy [ i ] ) ; } p r o c e s s ( ) ; p r i n t f ( ”%d\n” , r e s ) ; return 0 ; } 53 5.13 Smallest Enclosing Circle O(N 3 ), compute Convex Hull first! or it will be quite slow! double GetCos ( CPoint p0 , CPoint p1 , CPoint p2 ) { return dot ( p0 , p1 , p2 ) / d i s ( p0 , p1 ) / d i s ( p0 , p2 ) ; } int a l l i n ( CPoint p [ ] , int n , int i , int j , int k ) { fo r ( int l = 0 ; l <n ; l ++) i f ( l != i && l != j && l !=k ) { i f ( ( c r o s s (p [ i ] , p [ j ] , p [ k ]) >0)ˆ( c r o s s (p [ i ] , p [ j ] dcmp ( GetCos ( p [ k ] , p [ i ] , p [ j ])+ GetCos ( p [ l ] , p [ i ] i f ( ( c r o s s (p [ j ] , p [ k ] , p [ i ]) >0)ˆ( c r o s s (p [ j ] , p [ k ] dcmp ( GetCos ( p [ i ] , p [ k ] , p [ j ])+ GetCos ( p [ l ] , p [ k ] i f ( ( c r o s s (p [ i ] , p [ j ] , p [ k ]) >0)ˆ( c r o s s (p [ i ] , p [ l ] dcmp ( GetCos ( p [ j ] , p [ k ] , p [ i ])+ GetCos ( p [ l ] , p [ k ] } return 1 ; } , p [ l ]) >0) && , p [ j ] ) ) > 0 ) return 0 ; , p [ l ]) >0) && , p [ j ] ) ) > 0 ) return 0 ; , p [ k]) >0) && , p [ i ] ) ) > 0 ) return 0 ; double S m a l l e s t E n c l o s i n g C i r c l e ( CPoint p [ ] , int n , CPoint &cp ) { int i , j , k ; double di , cos1 , cos2 , co , s i , r =0; i f ( n = = 1 ) { cp = p [ 0 ] ; return 0 ; } i f ( n == 2 ) { cp . x = ( p [ 0 ] . x + p [ 1 ] . x ) / 2 ; cp . y = ( p [ 0 ] . y + p [ 1 ] . y ) / 2 ; return d i s ( p [ 0 ] , p [ 1 ] ) / 2 ; } fo r ( i = 0 ; i <n ; i ++) for ( j=i + 1 ; j <n ; j ++) { d i = d i s ( p [ i ] , p [ j ] ) ; c o s 1 = c o s 2 = −2; i f ( dcmp ( di−r ∗ 2 ) > 0 ) r = d i / 2 ; f o r ( k = 0 ; k<n ; k++) i f ( k!= i && k!= j ) { co = GetCos ( p [ k ] , p [ i ] , p [ j ] ) ; i f ( dcmp ( c r o s s ( p [ i ] , p [ j ] , p [ k ] ) ) > 0 ) { i f ( co>c o s 1 ) c o s 1=co ; } e l s e i f ( co>c o s 2 ) c o s 2=co ; } i f ( dcmp ( c o s 1 )<=0 && dcmp ( c o s 2 ) <=0 ) { cp . x = ( p [ i ] . x + p [ j ] . x ) / 2 ; cp . y = ( p [ i ] . y + p [ j ] . y ) / 2 ; return d i / 2 ; } } r = 1 e30 ; fo r ( i = 0 ; i <n ; i ++) for ( j=i + 1 ; j <n ; j ++) { di = dis ( p [ i ] , p [ j ] ) ; f o r ( k=j + 1 ; k<n ; k++) { co = GetCos ( p [ k ] , p [ j ] , p [ i ] ) ; s i = s q r t (1− s q r ( co ) ) ; i f ( dcmp ( d i / s i /2− r )<0 && a l l i n ( p , n , i , j , k ) ) { r=d i / s i / 2 ; G e t C i r c l e C e n t e r ( p [ i ] , p [ j ] , p [ k ] , cp ) ; } } } return r ; } 54 5.14 Smallest Enclosing Ball const double e p s = 1 e −10; struct p o i n t t y p e { double x , y , z ; } ; int npoint , n o u t e r ; point type point [ 1 0 0 0 0 ] , outer [ 4 ] , res ; double r a d i u s , tmp ; i n l i n e double d i s t ( p o i n t t y p e p1 , p o i n t t y p e p2 ) { double dx=p1 . x−p2 . x , dy=p1 . y−p2 . y , dz=p1 . z−p2 . z ; return ( dx∗dx + dy∗dy + dz ∗ dz ) ; } i n l i n e double dot ( p o i n t t y p e p1 , p o i n t t y p e p2 ) { return p1 . x∗p2 . x + p1 . y∗p2 . y + p1 . z ∗p2 . z ; } void m i n b a l l ( int n ) { ball (); i f ( nouter <4 ) f o r ( int i = 0 ; i <n; ++ i ) i f ( d i s t ( r e s , p o i n t [ i ]) − r a d i u s >e p s ) { o u t e r [ n o u t e r ]= p o i n t [ i ] ; ++n o u t e r ; minball ( i ) ; −−n o u t e r ; i f ( i >0 ) { p o i n t t y p e Tt = p o i n t [ i ] ; memmove(& p o i n t [ 1 ] , & p o i n t [ 0 ] , s i z e o f ( p o i n t t y p e ) ∗ i ) ; p o i n t [ 0 ] = Tt ; } } } 55 void b a l l ( ) { p o i n t t y p e q [ 3 ] ; double m[ 3 ] [ 3 ] , s o l [ 3 ] , L [ 3 ] , d e t ; int i , j ; res . x = res . y = res . z = radius = 0; switch ( n o u t e r ) { case 1 : r e s=o u t e r [ 0 ] ; break ; case 2 : r e s . x=( o u t e r [ 0 ] . x+o u t e r [ 1 ] . x ) / 2 ; r e s . y=( o u t e r [ 0 ] . y+o u t e r [ 1 ] . y ) / 2 ; r e s . z=( o u t e r [ 0 ] . z+o u t e r [ 1 ] . z ) / 2 ; r a d i u s=d i s t ( r e s , o u t e r [ 0 ] ) ; break ; case 3 : f o r ( i = 0 ; i <2; ++ i ) { q [ i ] . x=o u t e r [ i + 1 ] . x−o u t e r [ 0 ] . x ; q [ i ] . y=o u t e r [ i + 1 ] . y−o u t e r [ 0 ] . y ; q [ i ] . z=o u t e r [ i + 1 ] . z−o u t e r [ 0 ] . z ; } f o r ( i = 0 ; i <2; ++ i ) for ( j = 0 ; j <2; ++ j ) m[ i ] [ j ]= dot ( q [ i ] , q [ j ] ) ∗ 2 ; f o r ( i = 0 ; i <2; ++ i ) s o l [ i ]= dot ( q [ i ] , q [ i ] ) ; i f ( f a b s ( d e t=m[ 0 ] [ 0 ] ∗m[ 1 ] [ 1 ] −m[ 0 ] [ 1 ] ∗m[ 1 ] [ 0 ] ) < e p s ) return ; L [ 0 ] = ( s o l [ 0 ] ∗m[ 1 ] [ 1 ] − s o l [ 1 ] ∗m[ 0 ] [ 1 ] ) / d e t ; L [ 1 ] = ( s o l [ 1 ] ∗m[ 0 ] [ 0 ] − s o l [ 0 ] ∗m[ 1 ] [ 0 ] ) / d e t ; r e s . x=o u t e r [ 0 ] . x+q [ 0 ] . x∗L [ 0 ] + q [ 1 ] . x∗L [ 1 ] ; r e s . y=o u t e r [ 0 ] . y+q [ 0 ] . y∗L [ 0 ] + q [ 1 ] . y∗L [ 1 ] ; r e s . z=o u t e r [ 0 ] . z+q [ 0 ] . z ∗L [ 0 ] + q [ 1 ] . z ∗L [ 1 ] ; r a d i u s=d i s t ( r e s , o u t e r [ 0 ] ) ; break ; case 4 : f o r ( i = 0 ; i <3; ++ i ) { q [ i ] . x=o u t e r [ i + 1 ] . x−o u t e r [ 0 ] . x ; q [ i ] . y=o u t e r [ i + 1 ] . y−o u t e r [ 0 ] . y ; q [ i ] . z=o u t e r [ i + 1 ] . z−o u t e r [ 0 ] . z ; s o l [ i ]= dot ( q [ i ] , q [ i ] ) ; } f o r ( i =0; i <3;++ i ) for ( j =0; j <3;++ j ) m[ i ] [ j ]= dot ( q [ i ] , q [ j ] ) ∗ 2 ; d e t = m[ 0 ] [ 0 ] ∗m[ 1 ] [ 1 ] ∗m[ 2 ] [ 2 ] + m[ 0 ] [ 1 ] ∗m[ 1 ] [ 2 ] ∗m[ 2 ] [ 0 ] + m[ 0 ] [ 2 ] ∗m[ 2 ] [ 1 ] ∗m[ 1 ] [ 0 ] − m[ 0 ] [ 2 ] ∗m[ 1 ] [ 1 ] ∗m[ 2 ] [ 0 ] − m[ 0 ] [ 1 ] ∗m[ 1 ] [ 0 ] ∗m[ 2 ] [ 2 ] − m[ 0 ] [ 0 ] ∗m[ 1 ] [ 2 ] ∗m [ 2 ] [ 1 ] ; i f ( f a b s ( d e t )< e p s ) return ; f o r ( j = 0 ; j <3; ++ j ) { for ( i = 0 ; i <3; ++ i ) m[ i ] [ j ]= s o l [ i ] ; L [ j ] = ( m[ 0 ] [ 0 ] ∗m[ 1 ] [ 1 ] ∗m[ 2 ] [ 2 ] + m[ 0 ] [ 1 ] ∗m[ 1 ] [ 2 ] ∗m[ 2 ] [ 0 ] + m[ 0 ] [ 2 ] ∗m[ 2 ] [ 1 ] ∗m[ 1 ] [ 0 ] − m[ 0 ] [ 2 ] ∗m[ 1 ] [ 1 ] ∗m[ 2 ] [ 0 ] − m[ 0 ] [ 1 ] ∗m[ 1 ] [ 0 ] ∗m[ 2 ] [ 2 ] − m[ 0 ] [ 0 ] ∗m[ 1 ] [ 2 ] ∗m[ 2 ] [ 1 ] ) / det ; for ( i = 0 ; i <3; ++ i ) m[ i ] [ j ]= dot ( q [ i ] , q [ j ] ) ∗ 2 ; } r e s=o u t e r [ 0 ] ; f o r ( i = 0 ; i <3; ++ i ) { r e s . x += q [ i ] . x ∗ L [ i ] ; r e s . y += q [ i ] . y ∗ L [ i ] ; r e s . z += q [ i ] . z ∗ L [ i ] ; } r a d i u s=d i s t ( r e s , o u t e r [ 0 ] ) ; } } 56 Chapter 6 Classic Problems 6.1 Bernoulli Number Generator Note: fraction.h contains a Fraction Class (Section 1.4 on Page 8) #include<f r a c t i o n . h> Fraction a [ 2 2 ] ; int c [ 2 2 ] [ 2 2 ] ; int main ( ) { int i , j , k ,m; c [0][0] = 1; fo r ( i =1; i <=21; i ++) { c [ i ][0] = 1; c [ i ] [ i ] = 1; f o r ( j =1; j <i ; j ++) c [ i ] [ j ] = c [ i − 1 ] [ j ] + c [ i − 1 ] [ j − 1 ] ; } a[0] = 0; while ( c i n >>k ) { a [ k +1] = F r a c t i o n ( 1 , k + 1 ) ; m = k+1; f o r ( i=k ; i >=1; i −−) { a [ i ] = 0; f o r ( j=i +1; j<=k+1; j ++) i f ( ( j −i +1)%2==0) a [ i ] = a [ i ]+a [ j ] ∗ c [ j ] [ j −i + 1 ] ; e l s e a [ i ] = a [ i ]−a [ j ] ∗ c [ j ] [ j −i + 1 ] ; a [ i ] = a [ i ] ∗ Fraction (1 , i ) ; m = lcm (m, a [ i ] . g e t d e n o m i n a t o r ( ) ) ; } c o u t << m << ’ ’ ; f o r ( i=k+1; i >0; i −−) c o u t << a [ i ] ∗ m<< ’ ’ ; c o u t << 0 << e n d l ; } return 0 ; } 57 6.2 Baltic OI’99 Expressions f (n, d) is the number of trees whose depth is less or equal than d. int f [ maxn ] [ maxd ] , h [ maxn ] [ maxn ] , n , d ; int main ( ) { ifstream cin ( ” input . txt ” ) ; int i , j , k ; fo r ( d = 1 ; d<maxd ; d++) { memset ( h , 0 , s i z e o f ( h ) ) ; f o r ( i = 0 ; i<=d ; i ++) h [ i ] [ 0 ] = 1 ; f o r ( i = 1 ; i <maxn ; i ++) for ( j=i −d ; j<=i ; j ++) i f ( j >=0) h [ i ] [ j ]=h [ i − 1 ] [ j ]+h [ i ] [ j − 1 ] ; f o r ( i =1; i <maxn ; i ++) f [ i ] [ d]=h [ i ] [ i ] ; } while ( c i n >>n>>d && n ) cout << f [ n / 2 ] [ d ] − f [ n / 2 ] [ d−1]<<e n d l ; return 0 ; } 6.3 Bead Coloring — Pólya Theory Use C colors to color L-bead necklace , the non-isomorphic number of the necklaces is : If L is odd , L X L+1 1 2 (LC + C (K,L) ) f (C, L) = 2L K=1 If L is even, f (C, L) = L X L 1 L L ( (C 2 + C 2 +1 ) + C (K,L) ) 2L 2 K=1 int ans , n ,m, mk [ maxn ] , i d [ maxn ] , num ; int main ( ) { int i , j , k , l , d , u , p [ maxn ] ; while ( c i n >>n>>m && n && m) { f o r ( p [ 0 ] = i = 1 ; i<=m; i ++) p [ i ]=p [ i −1]∗n ; f o r ( ans=num=i =0; i <m; i ++) i d [ i ]= i ; f o r ( l =0; l <2; l ++){ f o r ( i =0; i <m; i ++) { memset (mk, 0 , s i z e o f (mk ) ) ; for ( k=j =0; j <m; j ++) i f ( ! mk [ i d [ j ] ] ) for ( k++, u=i d [ j ] ; ! mk [ u ] ; u=i d [ ( u+i )%m] ) mk [ u ] = 1 ; num++; ans+=p [ k ] ; } s t d : : r e v e r s e ( id , i d+m) ; } cout<<ans /num<<e n d l ; } return 0 ; } 58 6.4 Binary Stirling Number Parity of the Stirling number of the second kind #define int long long int c a l c ( int n , int k ) { i f ( k ==0 ) i f ( n==0 ) return 1 ; e l s e return 0 ; e l s e i f ( k ==1 ) return 1 ; e l s e { int p = 0 , p2 = 1 ; while ( k>p2 ∗ 2 | | n−k/2>p2 ) { p++; p2 <<=1; } i f ( k>p2 ) return c a l c ( n−p2 , k−p2 ) ; i f ( n−k>=p2 / 2 ) return c a l c ( n−p2 / 2 , k ) ; return 0 ; } } 6.5 Box Surface Distance int r , L , H,W, x1 , y1 , z1 , x2 , y2 , z2 ; void t u r n ( int i , int j , int x , int y , int z , int x0 , int y0 , int L , int W, int H) { i f ( z ==0){ int R=x∗x+y∗y ; i f (R<r ) r=R ; } e l s e { i f ( i >=0 && i < 2 ) t u r n ( i +1, j , x0+L+z , y , x0+L−x , x0+L , y0 , H,W, L ) ; i f ( j >=0 && j < 2 ) t u r n ( i , j +1 , x , y0+W+z , y0+W−y , x0 , y0+W, L , H,W) ; i f ( i <=0 && i >−2) t u r n ( i −1, j , x0−z , y , x−x0 , x0−H, y0 , H,W, L ) ; i f ( j <=0 && j >−2) t u r n ( i , j −1 , x , y0−z , y−y0 , x0 , y0−H, L , H,W) ; } } int main ( ) { while ( c i n >> L >> W >> H >> x1 >> y1 >> z1 >> x2 >>y2 >> z2 ) { i f ( z1 !=0 && z1 !=H) i f ( y1 = = 0 | | y1==W) { s t d : : swap ( y1 , z1 ) ; s t d : : swap ( y2 , z2 ) ; s t d : : swap (W,H ) ; } e l s e { s t d : : swap ( x1 , z1 ) ; s t d : : swap ( x2 , z2 ) ; s t d : : swap (L ,H ) ; } i f ( z1==H) z1 =0, z2=H−z2 ; r=0 x 3 f f f f f f f ; t u r n ( 0 , 0 , x2−x1 , y2−y1 , z2 ,−x1 ,−y1 , L ,W,H ) ; cout<<r<<e n d l ; } return 0 ; } 6.6 Calculate Expression char expr [MAX+ 1 ] ; int next [MAX] , s t a c k [MAX] , top ; double c a l c ( int L , int R ) ; void p r e f i x ( ) { int i ; top =−1; fo r ( i = 0 ; expr [ i ]; ++ i ) { next [ i ]= −1; i f ( expr [ i ]== ’ ( ’ ) s t a c k [++top ]= i ; e l s e i f ( expr [ i ]== ’ ) ’ ) next [ s t a c k [ top −−]]= i ; } } 59 double getnum ( int &L ) { double r e s = 0 ; i f ( expr [ L]== ’ ( ’ ) { r e s=c a l c (L+1 , next [ L ] − 1 ) ; L=next [ L ] + 1 ; } e l s e while ( i s d i g i t ( expr [ L ] ) ) r e s=r e s ∗10+ expr [ L++]− ’ 0 ’ ; return r e s ; } void p r o c e s s ( double switch ( op ) { case ’+ ’ : a case ’− ’ : a case ’ ∗ ’ : a default : a } } &a , double b , char op ) { += −= ∗= /= b ; break ; b ; break ; b ; break ; b; double c a l c ( int L , int R) { double a , b , c ; char op1 , op2 ; i f ( next [ L] == R ) return c a l c (L+1 , R−1); a = 0 ; op1 = ( expr [ L]== ’− ’ ? ’− ’ : ’+ ’ ) ; L = ( expr [ L]== ’+ ’ | | expr [ L]== ’− ’ ? L + 1 : L ) ; fo r ( b = getnum (L ) ; L<R ; ) { op2=expr [ L++]; c=getnum (L ) ; i f ( op2==’+ ’ | | op2==’− ’ | | op1==’ ∗ ’ | | op1==’ / ’ ) { p r o c e s s ( a , b , op1 ) ; b=c ; op1=op2 ; } e l s e p r o c e s s ( b , c , op2 ) ; } p r o c e s s ( a , b , op1 ) ; return a ; } void main ( ) { s c a n f ( ”%s ” , expr ) ; p r e f i x ( ) ; p r i n t f ( ” %.10 l f \n” , c a l c ( 0 , s t r l e n ( expr ) ) ) ; } 6.7 Cartesian Tree int l s o n [ maxn ] , r s o n [ maxn ] , pnt [ maxn ] , r o o t , n ; void B u i l d C a r t e s i a n T r e e ( int a [ ] , int n ) { int i , j ; fo r ( i = 0 ; i <n ; j=i ++) { pnt [ i ]= i − 1 ; l s o n [ i ]= r s o n [ i ]= −1; j=i ; while ( pnt [ j ]>=0 && a [ i ]>a [ pnt [ j ] ] ) j = pnt [ j ] ; i f ( j != i ) { pnt [ i ]= pnt [ j ] ; l s o n [ i ]= j ; pnt [ j ]= i ; } ; i f ( pnt [ i ] >=0) r s o n [ pnt [ i ] ] = i ; } fo r ( i =0; i <n ; i ++) i f ( pnt [ i ] < 0 ) r o o t=i ; } 60 6.8 Catalan Number Generator \ \ Catalan [ 1 9 ] = 1 7 6 7 2 6 3 1 9 0 < 2ˆ31 \ \ Catalan [ 3 5 ] = 3 1 1 6 2 8 5 4 9 4 9 0 7 3 0 1 2 6 2 < 2ˆ63 \ \ Catalan [ 1 0 0 ] = 8 9 6 5 1 9 9 4 7 0 9 0 1 3 1 4 9 6 6 8 7 1 7 0 0 7 0 0 7 4 1 0 0 6 3 2 4 2 0 8 3 7 5 2 1 5 3 8 7 4 5 9 0 9 3 2 0 #define maxn 1 0 0 0 #define maxlen 7 0 0 #define maxpnum 4 0 0 int prime [ maxpnum ] , primepos [ maxn ∗ 2 ] , num [ maxpnum ] , pnum ; struct HP{ int l e n ; int s [ maxlen ] ; } ; void PrintHP (HP x ) { for ( int i=x . l e n ; i > 0 ; i −−) cout<<x . s [ i ] ; } void Multi (HP &x , int k ) { int i ; f o r ( i =1; i<=x . l e n ; i ++) x . s [ i ]∗=k ; x . l e n +=8; // l o g ( 1 0 , maxn ∗ 2 ) ; fo r ( i =1; i<=x . l e n ; i ++) { x . s [ i +1]+=x . s [ i ] / 1 0 ; x . s [ i ]%=10; } while ( x . l e n >1 && !x . s [ x . l e n ] ) x . l e n −−; } void F a c t o r i z e ( int x , int f l a g ) { fo r ( int i = 0 ; prime [ i ] ∗ prime [ i ]<=x ; i ++) while ( x%prime [ i ] = = 0 ) { x/=prime [ i ] ; num [ i ]+= f l a g ; } i f ( x >1) num [ primepos [ x]]+= f l a g ; } HP Catalan ( int n ) { HP x ; memset(&x , 0 , s i z e o f ( x ) ) ; x . l e n = 1 ; x . s [ 1 ] = 1 ; memset (num, 0 , s i z e o f (num ) ) ; int i , j ; fo r ( i =1; i<=n ; i ++) { F a c t o r i z e ( 2 ∗ n+1− i , 1 ) ; F a c t o r i z e ( i , − 1 ) ; } F a c t o r i z e ( n+1 , −1); fo r ( i =0; i <pnum ; i ++) while (num [ i ]−−>0) Multi ( x , prime [ i ] ) ; return x ; } void I n i t P r i m e s ( ) { int i , j ; pnum= 0 ; memset ( primepos , 0 , s i z e o f ( primepos ) ) ; fo r ( i =2; i<=maxn ∗ 2 ; i ++) i f ( ! primepos [ i ] ) { primepos [ i ]=pnum ; prime [ pnum++]= i ; f o r ( j=i+i ; j<=maxn ∗ 2 ; j+=i ) primepos [ j ]= −1; } } void main ( ) { I n i t P r i m e s ( ) ; int n ; while ( c i n >>n ) { PrintHP ( Catalan ( n ) ) ; cout<<e n d l ; } } 61 6.9 Coloring Regular Polygon Coloring regular n-vertex polygon with m white and n − m black. When n = 17 and m = 8 OUTPUT : 750 int c [ maxn ] [ maxn ] , ans , n , m; int gcd ( int i , int j ) { i f ( j ==0) return i ; e l s e return gcd ( j , i%j ) ; } int main ( ) { c i n >>n>>m; int i , j , k , l , d ; c [0][0]=1; fo r ( i = 1 ; i <maxn ; i ++) { c [ i ][0]=1; f o r ( j = 1 ; j<=i ; j ++) c [ i ] [ j ]= c [ i − 1 ] [ j ]+ c [ i − 1 ] [ j − 1 ] ; } fo r ( k=0;k<m; k++) { d=gcd (m, k ) ; i f ( n∗d % m = = 0 ) { l=n∗d/m; ans+=c [ l − 1 ] [ d − 1 ] ; } } i f (m%2==0) { i f ( n%2==0) ans+=(m/ 2 ) ∗ c [ n /2 −1][m/2 −1]; i f (m==2) ans+=(m/ 2 ) ∗ ( n − 1 ) ; e l s e f o r ( i =2−n %2; i<=n−(m− 2 ) ; i +=2) ans+=(m/ 2 ) ∗ ( i −1)∗ c [ ( n−i ) / 2 − 1 ] [ (m−2)/2 −1]; } e l s e f o r ( i =2−n %2; i<=n−(m− 1 ) ; i +=2) ans+=m∗ c [ ( n−i ) / 2 − 1 ] [ (m−1)/2 −1]; cout<<ans / ( 2 ∗m)<<e n d l ; return 0 ; } 6.10 Counting Inverse Pairs #include<i o s t r e a m . h> #include<f s t r e a m . h> #include<a l g o r i t h m > #define maxn 1 0 0 0 0 int a [ maxn ] , t [ maxn ] , n , ans ; void s o r t ( int b , int e ) { i f ( e−b<=0) return ; int mid=(b+e ) / 2 , p1=b , p2=mid+1, i=b ; s o r t ( b , mid ) ; s o r t ( mid+1, e ) ; while ( p1<=mid | | p2<=e ) i f ( p2>e | | ( p1<=mid && a [ p1]<=a [ p2 ] ) ) t [ i ++]=a [ p1 ++]; e l s e { t [ i ++]=a [ p2 ++]; ans+=mid−p1 + 1 ; } fo r ( i=b ; i<=e ; i ++)a [ i ]= t [ i ] ; } int main ( ) { ifstream cin ( ” input . txt ” ) ; int i , j ; while ( c i n >>n ) { f o r ( i =0; i <n ; i ++) c i n >>a [ i ] ; ans = 0 ; s o r t ( 0 , n − 1 ) ; // Counting I n v e r s e Number cout<<”Minimum exchange o p e r a t i o n s : ”<<ans<<e n d l ; } return 0 ; } 62 6.11 Counting Trees // Rooted {1 , 5 , 11 , 20 , 30} = > {1 , 9 , 1842 , 12826228 , 354426847597 } // Non−Rooted { 1 , 3 , 1 0 , 2 5 , 3 0 } = > { 1 , 1 , 1 0 6 , 1 0 4 6 3 6 8 9 0 , 14830871802 } void main ( ) { ifstream cin ( ” input . txt ” ) ; int i , j , n ; memset ( s , 0 , s i z e o f ( s ) ) ; a [ 0 ] = 0 ; a [ 1 ] = 1 ; fo r ( i = 1 ; i <maxn− 1 ; i ++) { a [ i +1] = 0; f o r ( j = 1 ; j<=i ; j ++) { s [ i ] [ j ] = s [ i −j ] [ j ] + a [ i +1−j ] ; a [ i +1] += j ∗a [ j ] ∗ s [ i ] [ j ] ; } a [ i +1] /= i ; } while ( c i n >>n ) // a [ n ] = Rooted ; ans = Non−Rooted { int ans = a [ n ] ; f o r ( i = 1 ; 2 ∗ i<=n ; i ++) ans −= a [ i ] ∗ a [ n−i ] ; i f ( n%2==0 ) ans += ( a [ n / 2 ] + 1 ) ∗ a [ n / 2 ] / 2 ; c o u t << a [ n] < < ” ” << ans << e n d l ; } } 6.12 Eight Puzzle Problem Input: 012345678 123456780 Output: ST EP = 22 Common Part #define maxlen 1 0 #define s i z e 362880+1 const int l i n k [ 9 ] [ 5 ] = { { 2 , 1 , 3 } , { 3 , 0 , 2 , 4 } , { 2 , 1 , 5 } , { 3 , 0 , 4 , 6 } , {4 ,1 ,3 ,5 ,7} , {3 ,2 ,4 ,8} , {2 ,3 ,7} , {3 ,4 ,6 ,8} , {2 ,5 ,6} }; int s [ maxlen ] , p [ maxlen ] , mk [ s i z e ] , open [ s i z e ] , cur , t a i l ; void encode ( int ∗ s , int l e n , int &x ) { int i , j , k , l ; for ( x=0, i=l e n − 1 ; i >=0; x+=k∗p [ i −−]) fo r ( k=s [ i ] , j=i + 1 ; j <l e n ; j ++) i f ( s [ j ]< s [ i ] ) k−−; } void decode ( int ∗ s , int l e n , int x ) { int i , j , k , l ; for ( i=l e n − 1 ; i >=0; i −−){ s [ i ]=x/p [ i ] ; x%=p [ i ] ; } fo r ( i = 0 ; i <l e n ; i ++) for ( j = 0 ; j <i ; j ++) i f ( s [ j ]>=s [ i ] ) s [ j ]++; } void p r i n t ( int ∗ s , int l e n ) { f o r ( int i =0; i <l e n ; i ++) cout<<s [ i ] ; cout<<e n d l ; } 63 int main ( ) { ifstream cin ( ” input . txt ” ) ; char ch ; int i , s r c , d s t ; fo r ( p [ 0 ] = i = 1 ; i <maxlen ; i ++) p [ i ]=p [ i −1]∗ i ; fo r ( i =0; i <9; i ++) { c i n >>ch ; s [ i ]=ch− ’ 0 ’ ; } encode ( s , 9 , s r c ) ; fo r ( i =0; i <9; i ++) { c i n >>ch ; s [ i ]=ch− ’ 0 ’ ; } encode ( s , 9 , d s t ) ; s o l v e ( s r c , d s t ) ; cout<<cur<<” ”<<t a i l <<e n d l ; return 0 ; } Simple Breadth First Search void output ( int pos , int num) { i f ( pos ==1) cout<<” T o t a l number o f s t e p s = ”<<num<<e n d l ; e l s e output (mk [ open [ pos ] ] , num+1); decode ( s , 9 , open [ pos ] ) ; p r i n t ( s , 9 ) ; } void s o l v e ( int s r c , int d s t ) { int i , j , k , x , l , ps ; i f ( s r c==d s t ) { cout<<”SRC DST i s t h e same ! ”<<e n d l ; return ; } c u r = 0 ; t a i l = 1 ; open [ 1 ] = s r c ; mk [ s r c ] = 1 ; while(++cur<=t a i l ) { decode ( s , 9 , open [ c u r ] ) ; for ( ps = 0 ; s [ ps ] ; ps ++); f o r ( k = 1 ; k<=l i n k [ ps ] [ 0 ] ; k++) { s t d : : swap ( s [ ps ] , s [ l i n k [ ps ] [ k ] ] ) ; encode ( s , 9 , x ) ; i f ( ! mk [ x ] ) { mk [ x]= c u r ; open[++ t a i l ]=x ; i f ( x==d s t ) { output ( t a i l , 0 ) ; return ; } } s t d : : swap ( s [ ps ] , s [ l i n k [ ps ] [ k ] ] ) ; } } cout<<”No s o l u t i o n ! ”<<e n d l ; } Heuristic Breadth First Search int d [ s i z e ] , heap [ s i z e ] , hlen , h [ s i z e ] , d s t s [ maxlen ] ; int cmp( const int & i , const int & j ) { return h [ i ]>h [ j ] ; } void c a l c h ( int pos ) { int i , j , k ; h [ pos ]=d [ pos ] ; fo r ( i =0; i <9; i ++) i f ( s [ i ] ! = d s t s [ i ] ) h [ pos ]++; } void output ( int pos , int num) { i f ( pos ==1) cout<<” T o t a l number o f s t e p s = ”<<num<<e n d l ; e l s e output (mk [ open [ pos ] ] , num+1); decode ( s , 9 , open [ pos ] ) ; p r i n t ( s , 9 ) ; } 64 void s o l v e ( int s r c , int d s t ) { int i , j , k , x , l , ps ; i f ( s r c==d s t ) { cout<<”SRC DST i s t h e same ! ”<<e n d l ; return ; } t a i l = 1 ; open [ 1 ] = s r c ; mk [ s r c ] = 1 ; h l e n = 1 ; heap [ 0 ] = 1 ; d [ 1 ] = 0 ; decode ( s , 9 , s r c ) ; decode ( d s t s , 9 , d s t ) ; c a l c h ( 1 ) ; while ( hlen >0){ c u r=heap [ 0 ] ; s t d : : pop heap ( heap , heap+( hlen −−),cmp ) ; decode ( s , 9 , open [ c u r ] ) ; for ( ps = 0 ; s [ ps ] ; ps ++); f o r ( k = 1 ; k<=l i n k [ ps ] [ 0 ] ; k++) { s t d : : swap ( s [ ps ] , s [ l i n k [ ps ] [ k ] ] ) ; encode ( s , 9 , x ) ; i f ( ! mk [ x ] ) { mk [ x]= c u r ; open[++ t a i l ]=x ; d [ t a i l ]=d [ c u r ] + 1 ; c a l c h ( t a i l ) ; heap [ h l e n++]= t a i l ; s t d : : push heap ( heap , heap+hlen , cmp ) ; i f ( x==d s t ) { output ( t a i l , 0 ) ; return ; } } s t d : : swap ( s [ ps ] , s [ l i n k [ ps ] [ k ] ] ) ; } } cout<<”No s o l u t i o n ! ”<<e n d l ; } Double Breadth First Search int s t e p , d i [ s i z e ] ; void out1 ( int pos ) { i f ( pos >2) out1 (mk [ open [ pos ] ] ) ; s t e p ++; decode ( s , 9 , open [ pos ] ) ; p r i n t ( s , 9 ) ; } void out2 ( int pos ) { decode ( s , 9 , open [ pos ] ) ; p r i n t ( s , 9 ) ; i f ( pos >2) out2 (mk [ open [ pos ] ] ) ; s t e p ++; } void s o l v e ( int s r c , int d s t ) { int i , j , k , x , l , ps ; i f ( s r c==d s t ) { cout<<”SRC DST i s t h e same ! ”<<e n d l ; return ; } open [ 1 ] = s r c ; mk [ s r c ] = 1 ; d i [ s r c ] = 1 ; c u r =0; open [ 2 ] = d s t ; mk [ d s t ] = 2 ; d i [ d s t ] = 2 ; t a i l =2; while(++cur<=t a i l ) { decode ( s , 9 , open [ c u r ] ) ; for ( ps = 0 ; s [ ps ] ; ps ++); f o r ( k = 1 ; k<=l i n k [ ps ] [ 0 ] ; k++) { s t d : : swap ( s [ ps ] , s [ l i n k [ ps ] [ k ] ] ) ; encode ( s , 9 , x ) ; i f ( ! mk [ x ] ) { mk [ x]= c u r ; open[++ t a i l ]=x ; d i [ x]= d i [ open [ c u r ] ] ; } e l s e i f ( d i [ x ] ! = d i [ open [ c u r ] ] ) { s t e p =0; i f ( d i [ x ] = = 1 ) { out1 (mk [ x ] ) ; out2 ( c u r ) ; } else { out1 ( c u r ) ; out2 (mk [ x ] ) ; } cout<<” T o t a l number o f s t e p s = ”<<s t e p <<e n d l ; return ; } s t d : : swap ( s [ ps ] , s [ l i n k [ ps ] [ k ] ] ) ; } } cout<<”No s o l u t i o n ! ”<<e n d l ; } 65 6.13 Extended Honai Tower int P [ML ] [ ML] ,D[ML ] [ ML] ,T[ML ] [ ML ] ; void i n i t ( ) { int i , j , x , k , l ; fo r (P [ 0 ] [ 0 ] = l =1; l <ML; l ++) { P [ 0 ] [ l ] = P[ l ] [ 0 ] = 1 ; f o r ( i =1; i <l ; i ++) P [ i ] [ l −i ] = P [ i − 1 ] [ l −i ]+P [ i ] [ l −i − 1 ] ; } fo r ( i =0; i <ML; i ++) for ( k=j = 0 ; j <ML−i && k!=ML; j ++) f o r ( x=0;x<P [ i ] [ j ] ; x ++) { i f ( k==ML) break ; D[ i ] [ k++] = 1<< j ; } fo r ( i =0; i <ML; i ++) T[ i ] [ 0 ] = 0 ; fo r ( j =1; j <ML; j ++) for ( i =0; i <20; i ++) T [ i ] [ j ] = T [ i ] [ j −1]+D[ i ] [ j − 1 ] ; } int main ( ) { init (); fo r ( int a , b , c a s e c = 1 ; c i n >>a>>b && ( a | | b ) ; c a s e c++) c o u t << ” Case ” << c a s e c << ” : ” << T [ b − 3 ] [ a ] < < e n d l ; return 0 ; } 6.14 High Precision Square Root int x [ maxlen ] , y [ maxlen ] , z [ maxlen ] , bck [ maxlen ] , lx , ly , l z ; int I s S m a l l e r ( ) // i s z<=y ? { int i=l y ; while ( i >1 && z [ i ]==y [ i ] ) i −−; return ( z [ i ]<=y [ i ] ) ; } void S o l v e ( ) // yˆ2=x { int i , j , k ; l x =( l y + 1 ) / 2 ; l y=l x ∗ 2 ; memset ( x , 0 , s i z e o f ( x ) ) ; memset ( z , 0 , s i z e o f ( z ) ) ; fo r ( i=l x ; i >0; i −−){ f o r ( j = 1 ; j < 1 0 ; x [ i ]= j ++){ memcpy( bck , z , s i z e o f ( z ) ) ; z [ 2 ∗ i −1]++; for ( k=i ; k<=l x ; k++) { z [ i −1+k]+=2∗x [ k ] ; z [ i+k]+=z [ i −1+k ] / 1 0 ; z [ i −1+k ]%=10; } f o r ( k=l x+i ; k<=l y ; k++){ z [ k+1]+=z [ k ] / 1 0 ; z [ k ]%=10; } i f ( ! I s S m a l l e r ( ) ) break ; }; i f ( j <10) memcpy( z , bck , s i z e o f ( bck ) ) ; }; fo r ( i=l x ; i >0; i −−) cout<<x [ i ] ; cout<<e n d l ; } int main ( ) { char ch , s [ maxlen ] ; int i , j ; memset ( y , 0 , s i z e o f ( y ) ) ; c i n >>s ; l y=s t r l e n ( s ) ; fo r ( i =0; i <l y ; i ++) y [ i +1]= s [ ly −1− i ]− ’ 0 ’ ; Solve ( ) ; return 0 ; } 66 6.15 Largest Empty Rectangle O(N 2 ) int n , wx , wy , x [ maxn ] , y [ maxn ] , i d [ maxn ] ; int xx [ maxn ] , yy [ maxn ] , ans ; bool cmp( const int&i , const int&j ) { return x [ i ]<x [ j ] ; } void c a l c ( int i , int px , int py ) { int r e t , j , low =0, h i g h=wy ; fo r ( ; i <n ; i ++) i f ( x [ i ]>px ) { j =(high−low ) ∗ ( x [ i ]−px ) ; i f ( j >ans ) ans=j ; i f ( y [ i ]<py && y [ i ]>=low ) low = y [ i ] ; i f ( y [ i ]>=py && y [ i ]<=h i g h ) h i g h = y [ i ] ; } } int main ( ) { int i , j , k ; c i n >>wx>>wy>>n ; for ( i =0; i <n ; i ++) c i n >>x [ i ]>>y [ i ] ; x [ n]=y [ n ] = 0 ; n++; x [ n]=wx ; y [ n]=wy ; n++; fo r ( i =0; i <n ; i ++) i d [ i ]= i ; s t d : : s o r t ( id , i d+n , cmp ) ; fo r ( i =0; i <n ; i ++) { xx [ i ]=x [ i d [ i ] ] ; yy [ i ]=y [ i d [ i ] ] ; } fo r ( i =0; i <n ; i ++) { x [ i ]=xx [ i ] ; y [ i ]=yy [ i ] ; } s t d : : s o r t ( yy , yy+n ) ; k=s t d : : unique ( yy , yy+n)−yy ; ans =0; fo r ( i =0; i <n ; i ++) c a l c ( i , x [ i ] , y [ i ] ) ; fo r ( j =0; j <k ; j ++) c a l c ( 0 , 0 , yy [ j ] ) ; cout<<ans<<e n d l ; return 0 ; } O(D2 ) int x [ maxn ] , y [ maxn ] , x l i s t [ maxn ] , y l i s t [ maxn ] , nx , ny , ans , n , wx , wy ; char g [ maxd ] [ maxd ] ; int u [ maxd ] , d [ maxd ] , l [ maxd ] ; int main ( ) { int i , j , px , py , up , down , tmp ; ans =0; c i n >>wx>>wy>>n ; for ( i =0; i <n ; i ++) c i n >>x [ i ]>>y [ i ] ; nx=ny=n ; f or ( i =0; i <n ; i ++) { x l i s t [ i ]=x [ i ] ; y l i s t [ i ]=y [ i ] ; } x l i s t [ nx++]= y l i s t [ ny++]=0; x l i s t [ nx++]=wx ; y l i s t [ ny++]=wy ; s t d : : s o r t ( x l i s t , x l i s t+nx ) ; nx=s t d : : unique ( x l i s t , x l i s t +nx)− x l i s t ; s t d : : s o r t ( y l i s t , y l i s t+ny ) ; ny=s t d : : unique ( y l i s t , y l i s t +ny)− y l i s t ; fo r ( i = 0 ; i <nx ; i ++) memset ( g , 0 , n ) ; fo r ( i = 0 ; i <n ; i ++) { px = s t d : : lower bound ( x l i s t , x l i s t+nx , x [ i ] ) − x l i s t ; py = s t d : : lower bound ( y l i s t , y l i s t+ny , y [ i ] ) − y l i s t ; g [ px ] [ py ] = 1 ; } 67 fo r ( j = 0 ; j <ny − 1 ; j ++) { tmp = wx ∗ ( y l i s t [ j +1] − y l i s t [ j ] ) ; i f ( tmp > ans ) ans = tmp ; } fo r ( i = 1 ; i <nx ; i ++) { down = 0 ; up=ny −1; f o r ( j = 0 ; j <ny ; j ++) i f ( i = = 1 | | ∗ ( ∗ ( g+i −1)+ j ) ) { l [ j ]= i − 1 ; d [ j ] = 0 ; down=j ; } e l s e i f ( down > d [ j ] ) d [ j ] = down ; f o r ( j=ny − 1 ; j >=0; j −−) { i f ( i = = 1 | | ∗ ( ∗ ( g+i −1)+ j ) ) { u [ j ]=ny − 1 ; up=j ; } e l s e i f ( up < u [ j ] ) u [ j ] = up ; tmp = ( x l i s t [ i ] − x l i s t [ l [ j ] ] ) ∗ ( y l i s t [ u [ j ]] − y l i s t [ d [ j ] ] ) ; i f ( tmp>ans ) ans=tmp ; } } cout<<ans<<e n d l ; return 0 ; } O(N 2 ) int n , wx , wy , i d [ maxn ] , x [ maxn ] , y [ maxn ] , ans , xx [ maxn ] , yy [ maxn ] ; bool xcmp ( const int&i , const int & j ) { return x [ i ]<x [ j ] ; } bool ycmp ( const int&i , const int & j ) { return y [ i ]<y [ j ] ; } int main ( ) { int i , j , k , l , tmp , low , high , l a s t ; c i n >>wx>>wy>>n ; for ( i =0; i <n ; i ++) c i n >>x [ i ]>>y [ i x [ n]=y [ n ] = 0 ; n++; x [ n]=wx ; y [ n]=wy ; n++; fo r ( i =0; i <n ; i ++) i d [ i ]= i ; s t d : : s o r t ( id , i d+n , xcmp ) ; fo r ( i =0; i <n ; i ++) { xx [ i ]=x [ i d [ i ] ] ; yy [ i ]=y [ i d [ i fo r ( i =0; i <n ; i ++) { x [ i ]=xx [ i ] ; y [ i ]=yy [ i ] ; } s t d : : s o r t ( id , i d+n , ycmp ) ; fo r ( i =0; i <n ; i ++) { l = 0 ; l a s t =0; f o r ( j =0; j <n ; j ++) i f ( x [ i d [ j ]] < x [ i ] && y [ i d [ { i f ( y [ i d [ j ]] − l a s t > l ) l=y [ i d [ j ]] − l a s t l a s t=y [ i d [ j ] ] ; } i f ( wy−l a s t >l ) l=wy−l a s t ; i f ( l ∗x [ i ] > ans ) ans = l ∗x [ i ] ; low = 0 ; h i g h=wy ; for ( j=i +1; j <n ; j ++) { tmp = ( high−low ) ∗ ( x [ j ]−x [ i ] ) ; i f ( tmp> ans ) ans=tmp ; i f ( y [ j ]>=y [ i ] && y [ j ]< h i g h ) h i g h = y [ i f ( y [ j ]<=y [ i ] && y [ j ]> low ) low = y [ } } cout<<ans<<e n d l ; return 0 ; } 68 ]; ]]; } j ]] > l a s t ) ; j ]; j ]; 6.16 Last Non-Zero Digit of N! Smart Edition const int f f [ 1 0 ] = { 1 , 1 , 2 , 6 , 4 , 4 , 4 , 8 , 4 , 6 } ; int f a c t ( int n ) { int i , x ; i f ( n <5) return f f [ n ] ; x = ( f f [ n%10] ∗ 6 ) %10; fo r ( i = 1 ; i <=(n / 5 ) % 4 ; i ++) i f ( x = = 6 | | x ==2 ) x=(x + 1 0 ) / 2 ; e l s e x /=2; return ( f a c t ( n / 5 ) ∗ x ) % 1 0 ; } High Precision Edition int a [ 1 0 ] = { 6 , 1 , 2 , 6 , 4 , 4 , 4 , 8 , 4 , 6 } ; int b [ 4 ] = { 1 , 8 , 4 , 2 } ; void d i v i d e ( char s [ ] , int & l e n ) { int i ; char temp [ 2 0 0 ] ; fo r ( i = 0 ; i <l e n ; i ++) temp [ i ] = s [ i ] ∗ 2 ; temp [ l e n ] = 0 ; fo r ( i = 0 ; i <l e n ; i ++) i f ( temp [ i ] > 9 ) { temp [ i ] −=10; temp [ i +1]++; } fo r ( i = 0 ; i <l e n ; i ++) s [ i ] = temp [ i + 1 ] ; i f ( temp [ l e n ] = = 0 ) l e n −−; } int f a c t ( char s [ ] ) { int r e s u l e n t =1, power =0, l e n=s t r l e n ( s ) , i ; char temp ; i f ( l e n==1&&s [0]== ’ 0 ’ ) return 1 ; fo r ( i =0; i <l e n ; i ++) s [ i ]−= ’ 0 ’ ; fo r ( i =0; i <l e n / 2 ; i ++){ temp=s [ i ] ; s [ i ]= s [ l e n −1− i ] ; s [ l e n −1− i ]=temp ; } while ( l e n ) { r e s u l e n t=r e s u l e n t ∗ a [ s [ 0 ] % 1 0 ] % 1 0 ; divide ( s , len ) ; power+=(s [ 1 ] ∗ 1 0 + s [ 0 ] ) % 4 ; } r e s u l e n t=r e s u l e n t ∗b [ power %4]%10; return r e s u l e n t ; } 6.17 Least Common Ancestor int n , h , r o o t ; // maxh−1 = h = f l o o r ( l o g ( 2 , n − 1 ) ) int pnt [ maxn ] [ maxh ] , son [ maxn ] , next [ maxn ] , depth [ maxn ] ; int s t a c k [ maxn ] , mylog [ maxn ] ; int GetParent ( int x , int l e n ) { while ( l e n > 0 ) { x = pnt [ x ] [ mylog [ l e n ] ] ; l e n −= ( 1<<mylog [ l e n ] ) ; } return x ; } 69 int LCA( int x , int y ) // O( l o g N ) { int nx , ny , px , py , low , mid , h i g h ; low = 0 ; h i g h = depth [ x]< depth [ y ] ? depth [ x ] : depth [ y ] ; px = GetParent ( x , depth [ x]− h i g h ) ; py = GetParent ( y , depth [ y]− h i g h ) ; i f ( px == py ) return px ; while ( high−low >1) { mid = mylog [ high−low − 1 ] ; nx = pnt [ px ] [ mid ] ; ny = pnt [ py ] [ mid ] ; mid = h i g h − (1<<mid ) ; i f ( nx == ny ) low = mid ; e l s e { h i g h = mid ; px = nx ; py = ny ; } } return pnt [ px ] [ mylog [ high−low ] ] ; } int LCA 2 ( int x , int y ) // O( l o g ˆ 2 N ) { int low , mid , h i g h ; low = 0 ; mid = h i g h = depth [ x]< depth [ y ] ? depth [ x ] : depth [ y ] ; i f ( GetParent ( x , depth [ x]−mid ) ! = GetParent ( y , depth [ y]−mid ) ) while ( low+1<h i g h ) { mid = ( low + h i g h ) / 2 ; i f ( GetParent ( x , depth [ x]−mid ) ! = GetParent ( y , depth [ y]−mid ) ) h i g h = mid ; e l s e low = mid ; } e l s e low = h i g h ; return GetParent ( x , depth [ x]− low ) ; } void d f s ( int d , int c u r ) { int i , j ; s t a c k [ d ] = c u r ; depth [ c u r ] = d ; fo r ( j =1, i = 2 ; i<=d ; j ++, i ∗ = 2 ) pnt [ c u r ] [ j ]= s t a c k [ d−i ] ; fo r ( j=son [ c u r ] ; j ; j=next [ j ] ) d f s ( d +1 , j ) ; } void main ( ) { int i , j , k , l ; fo r ( i =0, j = 1 ; j <maxn ; i ++) { k = j ∗ 2 ; i f ( k>maxn ) k = maxn ; while ( j <k ) mylog [ j ++] = i ; } c i n >>n ; fo r ( i = 1 ; i<=n ; i ++) { son [ i ] = next [ i ] = 0 ; f o r ( j = 0 ; j<=h ; j ++) pnt [ i ] [ j ] = 0 ; } fo r ( i = 1 ; i <n ; i ++) { c i n >> j >> k ; pnt [ j ] [ 0 ] = k ; next [ j ]= son [ k ] ; son [ k]= j ; } fo r ( i = 1 ; i<=n ; i ++) i f ( pnt [ i ] [ 0 ] = = 0 ) { r o o t=i ; break ; } ; dfs ( 0 , root ) ; // P r e p r o c e s s Parent Array fo r ( c i n >>k ; k ; k − −) { c i n >> i >> j ; c o u t << LCA( i , j ) << e n d l ; } } 70 6.18 Longest Common Substring O(N log N ), using Suffix Sort with LCP information int LCS( char ∗ s1 , int l 1 , char ∗ s2 , int l 2 , int & i 1 , int & i 2 ) { strcpy ( s , s1 ) ; s [ l 1 ]= ’ $ ’ ; s t r c p y ( s+l 1 +1 , s 2 ) ; n=l 1+l 2 +1; SuffixSort ( ) ; GetHeight ( ) ; // s [ l 1 ] = 0 ; int i , j , l = 0 ; i 1 = i 2 = 0 ; fo r ( i = 1 ; i <n ; i ++) { i f ( h e i g h t [ i ]>= l && i d [ i −1]< l 1 && i d [ i ]> l 1 ) { l = h e i g h t [ i ] ; i 1 = i d [ i − 1 ] ; i 2 = i d [ i ]− l 1 − 1 ; } i f ( h e i g h t [ i ]>= l && i d [ i ]< l 1 && i d [ i −1]> l 1 ) { l = height [ i ] ; i1 = id [ i ] ; i 2 = i d [ i −1]− l 1 − 1 ; } } return l ; } O(N 2 ), using KMP int LCS( char ∗ s1 , int l 1 , char ∗ s2 , int l 2 , int & a n s i , int & a n s j ) { int i , j , k , l , ans = 0 ; a n s i = 0 ; a n s j =0; fo r ( i = 0 ; i <l 1 −ans ; i ++) { m a k e f a i l ( s 1+i , l 1 −i ) ; kmp ( s2 , l 2 , s 1+i , l 1 −i , 0 , l , j ) ; i f ( l >ans ) { ans=l ; a n s i=i ; a n s j=j ; } } return ans ; } Example Part char s 1 [ maxlen ] , s 2 [ maxlen ] ; int l 1 , l 2 ; int main ( ) { ifstream cin ( ” input . txt ” ) ; c i n >>s1>>s 2 ; l 1=s t r l e n ( s 1 ) ; l 2=s t r l e n ( s 2 ) ; int i 1 , i 2 , i , l = LCS( s1 , l 1 , s2 , l 2 , i 1 , i 2 ) ; cout<<l <<” ”<<i 1 <<” ”<<i 2 <<e n d l ; fo r ( i =0; i <l ; i ++) cout<<s 1 [ i 1+i ] ; cout<<e n d l ; fo r ( i =0; i <l ; i ++) cout<<s 2 [ i 2+i ] ; cout<<e n d l ; return 0 ; } M th Longest Common Substring #define h next // h [ i ] = L o n g e s t Common S u b s t r i n g o f s1 +0 and s2+i int mk [ maxn ] ; // a l r e a d y found a common s u b s t r i n g = s2 [ i . . mk [ i ] ) struct CAnswer { int pos , l e n ; } ans [ maxn ] ; bool newcmp ( const CAnswer &a , const CAnswer &b ) { i f ( a . l e n ! = b . l e n ) return a . l e n >b . l e n ; return a . pos<b . pos ; } 71 void LCS( char ∗ s1 , int l 1 , char ∗ s2 , int l 2 , int m) { strcpy ( s , s1 ) ; s [ l 1 ]= ’ $ ’ ; s t r c p y ( s+l 1 +1 , s 2 ) ; n=l 1+l 2 +1; SuffixSort ( ) ; GetHeight ( ) ; // s [ l 1 ] = 0 ; int i , j , k , p , u , v ; // computing l o n g e s t common p r e f i x b e t w e e n s1 +0 and s2+i memset ( h , 0 , s i z e o f ( h ) ) ; fo r ( i = 0 ; i <n ; i ++) i f ( i <n−1 && i d [ i ]< l 1 && i d [ i +1]> l 1 ) { k=maxlen ; f o r ( j=i + 1 ; j <n ; j ++) { i f ( i d [ j ]< l 1 ) break ; i f ( h e i g h t [ j ]<k ) k=h e i g h t [ j ] ; h [ j ]=k ; } i=j −1; } fo r ( i=n − 1 ; i > 0 ; i −−) i f ( i d [ i ]< l 1 && i d [ i −1]> l 1 ) { k=maxlen ; f o r ( j=i − 1 ; j >=0; j −−) { i f ( i d [ j ]< l 1 ) break ; i f ( h e i g h t [ j +1]<k ) k=h e i g h t [ j + 1 ] ; i f ( k>h [ j ] ) h [ j ]=k ; } i=j +1; } num= 0 ; // C o l l e c t Non−P o s i t i o n −C o v e r i n g Answer fo r ( i =0; i <n ; i ++) i f ( h [ rank [ i ] ] ! = 0 & & ( i = = 0 | | h [ rank [ i −1]]<=h [ rank [ i ] ] ) ) { k=rank [ i ] ; ans [ num ] . pos=i d [ k ] ; ans [ num ] . l e n=h [ k ] ; num++;} s t d : : s o r t ( ans , ans+num , newcmp ) ; memset (mk, 0 , s i z e o f (mk ) ) ; fo r ( i=j = 0 ; i <num && j <m; i ++) { k=rank [ ans [ i ] . pos ] ; // Check Non−S u b s t r i n g −C o v e r i n g i f ( mk [ k]>=h [ k ] ) continue ; int ok =1; f o r ( u=maxlen , p=k + 1 ; p<n ; p++) { i f ( h e i g h t [ p]<u ) u=h e i g h t [ p ] ; i f ( u<h [ k ] ) break ; i f (mk [ p]>=h [ k ] ) { ok = 0 ; break ; } } i f ( ! ok ) continue ; f o r ( u=maxlen , p=k − 1 ; p>=0; p−−) { i f ( h e i g h t [ p+1]<u ) u=h e i g h t [ p + 1 ] ; i f ( u<h [ k ] ) break ; i f (mk [ p]>=h [ k ] ) { ok = 0 ; break ; } } i f ( ! ok ) continue ; j ++; // Check Passed , S e t A l r e a d y Found S u b s t r i n g f o r ( v = 0 ; v<h [ k ] ; v++) i f ( mk [ rank [ i d [ k]+v ] ] < h [ k]−v ) mk [ rank [ i d [ k]+v ] ] = h [ k]−v ; // LENGTH h [ rank [ ans [ i ] . pos ] ] POSITION ans [ i ] . pos−l 1 −1 char ch = s [ ans [ i ] . pos + h [ rank [ ans [ i ] . pos ] ] ] ; s [ ans [ i ] . pos + h [ rank [ ans [ i ] . pos ] ] ] = 0 ; c o u t << s+ans [ i ] . pos << e n d l ; s [ ans [ i ] . pos + h [ rank [ ans [ i ] . pos ] ] ] = ch ; } } 72 6.19 Longest Non Descending Sub Sequence int LNDSS( int a [ ] , int n ) // L o n g e s t Non−d e s c e n d i n g Sub Sequence { int i , j , k , ∗ b=new int [ n +1] , ans =0; b [ ans]=−0 x 3 f 3 f 3 f 3 f ; fo r ( i =0; i <n ; i ++){ // l o w e r b o u n d f o r Asending Sub Squence j=s t d : : upper bound ( b , b+ans +1,a [ i ]) −b ; i f ( j >ans ) b[++ans ]=a [ i ] ; e l s e i f ( a [ i ]<b [ j ] ) b [ j ]=a [ i ] ; } delete b ; return ans ; } 6.20 Join and Disjoin Note: UnionFind.h contains a Union-Find Set (Section 1.10 on Page 11) #include<u n i o n f i n d . h> int Gather ( int x , int y ) { i f ( ! x && ! y ) return 0 ; i f ( ! x ) return f i n d ( y ) ; i f ( ! y ) return f i n d ( x ) ; Merge ( x , y ) ; return f i n d ( x ) ; } void J o i n ( int x , int y ) { int a=Gather ( x , y ) ; // x , y n e r v e r be z e r o int b=Gather ( vs [ x ] , vs [ y ] ) ; vs [ a]=b ; vs [ b]=a ; } void D i s j o i n ( int x , int y ) { int a=Gather ( x , vs [ y ] ) ; int b=Gather ( y , vs [ x ] ) ; vs [ a]=b ; vs [ b]=a ; } 73 6.21 Magic Square #define maxn 1 0 0 0 int a [ maxn ] [ maxn ] , n ; void b u i l d ( int n , int a [ ] [ maxn ] ) // No s o l u t i o n s when n=2! { int i , j , k , n2=n∗n ,m=n / 2 ,m2=m∗m; fo r ( i =0; i <n ; i ++) for ( j =0; j <n ; j ++) a [ i ] [ j ] = 0 ; i f ( n==2) return ; // No s o l u t i o n s i f ( n%2==1) f o r ( i =0, j=n / 2 , k=1;k<=n2 ; k++) { a[ i ][ j ] = k; i f ( ! a [ ( i+n−1)%n ] [ ( j +1)%n ] ) { i =( i+n−1)%n ; j =( j +1)%n ; } e l s e i =( i +1)%n ; } e l s e i f ( n%4==0) f o r ( k=0, i =0; i <n ; i ++) for ( j =0; j <n ; j ++) { a [ i ] [ j ] = ++k ; i f ( i%4==j % 4 | | i%4+j %4==3) a [ i ] [ j ] = n2+1−a [ i ] [ j ] ; } e l s e i f ( n%4==2) f o r ( i =0, j=m/ 2 , k=0;k<m2 ; k++) { i f ( ( i<=m/ 2 & & ! ( i==m/2&& j==m/ 2 ) ) | | ( i==m/2+1&& j==m/ 2 ) ) { // L a [ i ∗ 2 ] [ j ∗2+1]=k ∗ 4 + 1 ; a [ i ∗ 2 + 1 ] [ j ∗2]= k ∗4+2; a [ i ∗ 2 + 1 ] [ j ∗2+1]=k ∗ 4 + 3 ; a [ i ∗ 2 ] [ j ∗2]= k ∗4+4; } e l s e i f ( i >m/ 2 + 1 ) { // X a [ i ∗ 2 ] [ j ∗2]= k ∗ 4 + 1 ; a [ i ∗ 2 + 1 ] [ j ∗2+1]=k ∗4+2; a [ i ∗ 2 + 1 ] [ j ∗2]= k ∗ 4 + 3 ; a [ i ∗ 2 ] [ j ∗2+1]=k ∗4+4; } e l s e { // U a [ i ∗ 2 ] [ j ∗ 2 ]=k ∗ 4 + 1 ; a [ i ∗ 2 + 1 ] [ j ∗2]= k ∗4+2; a [ i ∗ 2 + 1 ] [ j ∗2+1]=k ∗ 4 + 3 ; a [ i ∗ 2 ] [ j ∗2+1]=k ∗4+4; } i f ( ! a [ ( i+m−1)%m∗ 2 ] [ ( j +1)%m∗ 2 ] ) i =( i+m−1)%m, j =( j +1)%m; e l s e i =( i +1)%m; } } int main ( ) { while ( c i n >>n ) { b u i l d ( n , a ) ; cout<<” Order ”<<n<<” : ”<<e n d l ; f o r ( int j , i =0; i <n ; i ++) { f or ( j =0; j <n ; j ++) cout<<a [ i ] [ j ]<< ’ ’ ; cout<<e n d l ; } } return 0 ; } 74 6.22 Optimal Binary Search Tree int n , a [ maxn ] , s [ maxn ] [ maxn ] , h [ maxn ] [ maxn ] , kk [ maxn ] [ maxn ] ; int s o l v e ( ) { int i , j , k , l ; memset ( h , 0 , s i z e o f ( h ) ) ; fo r ( i =1; i<=n ; i ++) { s [ i ] [ i ]=a [ i ] ; h [ i ] [ i ] = 0 ; kk [ f o r ( j=i +1; j<=n ; j ++) s [ i ] [ j ]= s [ i ] [ j −1]+a [ j ] ; } fo r ( l = 1 ; l <n ; l ++) { f o r ( i =1; i <n ; i ++) { j=i+l ; h [ i ] [ j ]=0 x 0 f f f f f f f f o r ( k=kk [ i ] [ j − 1 ] ; k<=kk [ i + 1 ] [ j ] ; k++) i f ( h [ i ] [ k−1]+h [ k + 1 ] [ j ]−a [ k]+ s [ i ] [ j ] h [ i ] [ j ] = h [ i ] [ k−1]+h [ k + 1 ] [ j ]+ s [ kk [ i ] [ j ] = k ; } } } return h [ 1 ] [ n ] ; } 6.23 i ] [ i ]= i ; ; < h[ i ][ j ]) { i ] [ j ]−a [ k ] ; Pack Rectangles — Cut Rectangles struct r e c t { int x1 , y1 , x2 , y2 ; } r [ maxm ] ; int mk [ maxm ] ; int i n t e r s e c t ( r e c t a , const r e c t &b , r e c t out [ 4 ] ) // b c u t a { i f ( b . x2<=a . x1 | | b . x1>=a . x2 | | b . y2<=a . y1 | | b . y1>=a . y2 ) return 0 ; i f ( b . x1<=a . x1 && b . x2>=a . x2 && b . y1<=a . y1 && b . y2>=a . y2 ) return −1; r e c t t ; int nout =0; i f ( b . x1>a . x1 ) { t=a ; t . x2=b . x1 ; a . x1=b . x1 ; out [ nout++]=t ; } i f ( b . x2<a . x2 ) { t=a ; t . x1=b . x2 ; a . x2=b . x2 ; out [ nout++]=t ; } i f ( b . y1>a . y1 ) { t=a ; t . y2=b . y1 ; a . y1=b . y1 ; out [ nout++]=t ; } i f ( b . y2<a . y2 ) { t=a ; t . y1=b . y2 ; a . y2=b . y2 ; out [ nout++]=t ; } return nout ; } int main ( ) { r e c t c u r r , t [ 4 ] ; int i , j , k , nn , nr , ans , r r , n ; c i n >>n ; r r =0; fo r ( i =0; i <n ; i ++){ c i n >> c u r r . x1 >> c u r r . y1 >> c u r r . x2 >> c u r r . y2 ; nr=r r ; mk [ r r ] = 1 ; r [ r r++]=c u r r ; f o r ( j = 0 ; j <nr ; j ++) { mk [ j ] = 1 ; nn=i n t e r s e c t ( r [ j ] , c u r r , t ) ; i f ( ! nn ) continue ; i f ( nn < 0 ) mk [ j ] = 0 ; e l s e { r [ j ] = t [−−nn ] ; while ( nn ) { mk [ r r ] = 1 ; r [ r r ++] = t [−−nn ] ; } } } f o r ( k=j = 0 ; j <r r ; j ++) i f (mk [ j ] ) r [ k++]=r [ j ] ; r r=k ; } fo r ( ans=i = 0 ; i <r r ; i ++) ans+=(r [ i ] . x2−r [ i ] . x1 ) ∗ ( r [ i ] . y2−r [ i ] . y1 ) ; cout<<ans<<e n d l ; return 0 ; } 75 6.24 Pack Rectangles — O(N 2 ) int x1 [ maxn ] , y1 [ maxn ] , x2 [ maxn ] , y2 [ maxn ] ; int y l i s t [ maxn ∗ 2 ] , i d [ maxn ] , n , ny ; bool cmp( const int&i , const int&j ) { return x1 [ i ]<x1 [ j ] ; } int GetAreaUnion ( ) { int i , j , k , rx , l , ans =0; fo r ( ny=0, i = 0 ; i <n ; i ++) { y l i s t [ ny++]=y1 [ i ] ; y l i s t [ ny++]=y2 [ i ] ; } s t d : : s o r t ( y l i s t , y l i s t+ny ) ; ny=s t d : : unique ( y l i s t , y l i s t +ny)− y l i s t ; fo r ( i = 0 ; i <n ; i ++) i d [ i ]= i ; s t d : : s o r t ( id , i d+n , cmp ) ; fo r ( j = 0 ; j <ny − 1 ; j ++){ rx = −0 x 3 f 3 f 3 f ; l =0; f o r ( k=0;k<n ; k++){ i = i d [ k ] ; i f ( y1 [ i ]<= y l i s t [ j ] && y2 [ i ]>= y l i s t [ j +1] && x2 [ i ]> rx ) { i f ( x1 [ i ]> rx ) l+=x2 [ i ]−x1 [ i ] ; e l s e l+=x2 [ i ]− rx ; rx = x2 [ i ] ; } } ans += l ∗ ( y l i s t [ j +1]− y l i s t [ j ] ) ; } return ans ; } 6.25 Parliament Given n > 0, find distinct positive numbers a1 + a2 + ... + ak = n that maximize a1 · a2 · ... · ak . int main ( ) { int n , k , p , i , c a s e n o ; fo r ( c i n >>c a s e n o ; caseno − −; ){ c i n >>n ; f o r ( p=n , k = 2 ; p>=k ; k++) p−=k ; k−−; i f ( p<=1){ for ( i =2; i <k ; i ++) cout<<i <<” ” ; cout<<k+p<<e n d l ; } e l s e i f ( p==k ) { for ( i =3; i<=k ; i ++) cout<<i <<” ” ; cout<<k+2<<e n d l ; } e l s e { for ( i =2+(p==k −1); i<=k ; i ++) i f ( i !=k−p +1) cout<<i <<” ” ; cout<<k+1<<e n d l ; } i f ( c a s e n o ) cout<<e n d l ; } return 0 ; } 6.26 π Generator int a =10000 ,b , c =2800 ,d , e , f [ 2 8 0 1 ] , g ; void GenPI ( ) { fo r ( ; b−c ; ) f [ b++]=a / 5 ; fo r ( ; d=0,g=c ∗ 2 ; c −=14, p r i n t f ( ”%.4d” , e+d/ a ) , e=d%a ) f o r ( b=c ; d+=f [ b ] ∗ a , f [ b]=d%−−g , d/=g−−,−−b ; d∗=b ) ; } 76 6.27 Plant Trees — Iteration const int maxlen = 5 0 0 0 5 ; const int maxn = 50000; int n , s t [ maxlen ] , a [ maxn ] , b [ maxn ] , c [ maxn ] , up ; int main ( ) { int i , more ; while ( c i n >>n ) { f o r ( i = 0 ; i <n ; i ++){ c i n >>a [ i ]>>b [ i ]>>c [ i ] ; i f (++b [ i ]>up ) up=b [ i ] ; } memset ( s t , 0 , s i z e o f ( s t ) ) ; f o r ( more = 1 ; more ; ) { more = 0 ; f o r ( i = 0 ; i <n ; i ++) i f ( s t [ a [ i ] ] + c [ i ]> s t [ b [ i ] ] ) { s t [ b [ i ] ] = s t [ a [ i ] ] + c [ i ] ; more = 1 ; } f o r ( i = 1 ; i<=up ; i ++) { i f ( s t [ i −1]+1< s t [ i ] ) { s t [ i −1]= s t [ i ] − 1 ; more = 1 ; i f ( s t [ i − 1 ] >s t [ i ] ) { s t [ i ]= s t [ i − 1 ] ; more = 1 ; } f o r ( i=up ; i > 0 ; i −−){ i f ( s t [ i ]−1> s t [ i − 1 ] ) { s t [ i −1]= s t [ i ] − 1 ; more = 1 ; i f ( s t [ i −1]> s t [ i ] ) { s t [ i ]= s t [ i − 1 ] ; more = 1 ; } } cout<<s t [ up] < < e n d l ; } return 0 ; } 6.28 } } } } Plant Trees — Segment Tree #define maxn 5 0 0 0 0 #define maxup 5 0 0 0 6 int nspan , span [ maxn ] [ 3 ] , up , t r e e [ maxup ] ; int iteam [ maxup ] , next [ maxup ] , num ; int funt comp ( const void ∗ a , const void ∗ b ) { return ( ( const int ∗ ) b ) [ 0 ] − ( ( const int ∗ ) a ) [ 0 ] ; } void add ( int r ) { for ( ; r<=up ; r+=r &( r ˆ ( r −1))) ++ t r e e [ r ] ; } int sum ( int r ) { int ans = 0 ; for ( ; r > 0 ; r−=r &( r ˆ ( r − 1 ) ) ) ans+=t r e e [ r ] ; return ans ; } void go ( ) { int j , k , i , ans = 0 ; up=0; fo r ( i = 0 ; i <nspan ; ++ i ) { s c a n f ( ”%d %d %d” , & span [ i ] [ 0 ] , & span [ i ] [ 1 ] , & span [ i ] [ 2 ] ) ; ++span [ i ] [ 0 ] ; + + span [ i ] [ 1 ] ; i f ( span [ i ] [ 1 ] > up ) up=span [ i ] [ 1 ] ; } q s o r t ( span , nspan , s i z e o f ( int ) ∗ 3 , funt comp ) ; fo r ( j =0; j<=up ; j ++) next [ j ]= j +1; next [ up ] = 0 ; memset ( t r e e , 0 , ( up+1)∗ s i z e o f ( int ) ) ; fo r ( i = 0 ; i <nspan ; i ++){ 77 k=sum ( span [ i ] [ 1 ] ) − sum ( span [ i ] [ 0 ] − 1 ) ; i f ( k>=span [ i ] [ 2 ] ) continue ; e l s e k=span [ i ] [ 2 ] − k ; j=span [ i ] [ 0 ] ; i f ( next [ j −1]!= j ) j=next [ j ] ; while ( k−−){ next [ span [ i ] [ 0 ] ] = next [ span [ i ] [ 0 ] − 1 ] = next [ j ] ; ans ++; add ( j ) ; j=next [ j ] ; } } p r i n t f ( ”%d\n” , ans ) ; } int main ( ) { while( 1== s c a n f ( ”%d” , & nspan ) ) go ( ) ; return 0 ; } 6.29 Range Maximum Query O(N log N ) Preprocess, O(1) Query int n , L , q , a [ maxn ] , h [ maxn ] [ maxL ] ; // maxL = s q r t {N} + 3 void P r e P r o c e s s ( ) { int i , j , l ; fo r ( i =0; i <n ; i ++) h [ i ] [ 0 ] = a [ i ] ; fo r ( j =1, l = 1 ; l ∗2<=n ; j ++, l ∗=2) for ( i = 0 ; i<=n−l ∗ 2 ; i ++) h [ i ] [ j ] = ( h [ i ] [ j −1]>h [ i+l ] [ j − 1 ] ) ? h [ i ] [ j − 1 ] : h [ i+l ] [ j − 1 ] ; } int Query ( int be , int ed ) // r e t u r n max{a [ op . . ed ] } { int j =0, l = 1 ; while ( 2 ∗ l<=ed−be + 1 ) { j ++; l ∗ = 2 ; } return ( h [ be ] [ j ]>h [ ed+1− l ] [ j ] ) ? h [ be ] [ j ] : h [ ed+1− l ] [ j ] ; } √ O(N ) Preprocess, O( N ) Query int a [ maxn ] , b [ maxL ] , n , L , q ; void P r e P r o c e s s ( ) { int i , j , up , k ; L = ( int ) s q r t ( n ) ; fo r ( i=k = 0 ; i <n ; k ++ ) { up=i+L ; i f ( up>n ) up = n ; f o r ( j=i + 1 ; j <up ; j ++) i f ( a [ j ]>a [ i ] ) i=j ; b [ k]= i ; i=up ; } } int Query ( int be , int ed ) // r e t u r n max{a [ op . . ed ] } { int i , up , u , v , k ; u = be / L ; v = ed / L ; k = be ; i f ( u<v ) { k=be ; up=(u+1)∗L ; f o r ( i=u + 1 ; i <v ; i ++) i f ( a [ b [ i ]] > a [ k ] ) k f o r ( i=be ; i <up ; i ++) i f ( a [ i ]>a [ k ] ) k f o r ( i=v∗L ; i<=ed ; i ++) i f ( a [ i ]>a [ k ] ) k } e l s e f o r ( i=be ; i<=ed ; i ++) i f ( a [ i ]>a [ k ] ) k return k ; } 78 = = = = b[ i ]; i; i; i; 6.30 Travelling Salesman Problem int n , x [ maxn ] , y [ maxn ] , i d [ maxn ] ; double g [ maxn ] [ maxn ] ; double d i s ( int x1 , int y1 , int x2 , int y2 ) { return s q r t ( ( x1−x2 ) ∗ ( x1−x2 )+( y1−y2 ) ∗ ( y1−y2 ) ) ; } double s o l v e ( ) { int i , j , k , l , l o o p ; double cur , ans=1e30 ; fo r ( i =0; i <n ; i ++) f o r ( j =0; j <n ; j ++) g [ i ] [ j ]= d i s ( x [ i ] , y [ i ] , x [ j ] , y [ j ] ) ; fo r ( k=0;k<n ; k++) { f o r ( l =0; l <50; l ++) { f o r ( i =0; i <n ; i ++) i d [ i ]= i ; s t d : : swap ( i d [ 0 ] , i d [ k ] ) ; s t d : : r a n d o m s h u f f l e ( i d +1, i d+n ) ; l o o p =1; while ( l o o p ) { l o o p =0; for ( i =1; i <n ; i ++) for ( j=i +1; j <n−1; j ++) i f ( g [ id [ i − 1 ] ] [ id [ i ] ] + g [ id [ j ] ] [ id [ j +1]] > g [ i d [ i − 1 ] ] [ i d [ j ] ] + g [ i d [ i ] ] [ i d [ j + 1 ] ] + 1 e −8 ) { l o o p =1; s t d : : r e v e r s e ( i d+i , i d+j +1); } }; f o r ( c u r =0, i = 0 ; i <n − 1 ; i ++) c u r+=g [ i d [ i ] ] [ i d [ i + 1 ] ] ; i f ( cur<ans ) ans=c u r ; } } return ans ; } 79 6.31 Tree Heights #define maxn 5 0 0 3 ∗ 4 int n , num , nbs [ maxn ] , next [ maxn ∗ 2 ] , h [ maxn ] ; int out1 [ maxn ] , out2 [ maxn ] , son1 [ maxn ] , i n [ maxn ] , v a l u e [ maxn ] ; int son [ maxn ] , pnt [ maxn ] , bro [ maxn ] , w e i g h t [ maxn ] , i d [ maxn ] ; void s o l v e ( ) { int i , j , k ( 1 ) , l ; id [ 1 ] = 1 ; weight [1]= in [ 1 ] = 0 ; fo r ( i =1; i<=k ; i ++) for ( j=son [ i d [ i ] ] ; j ; j=bro [ j ] ) i d [++k]= j ; fo r ( i =2; i<=n ; i ++) w e i g h t [ i ] = 1 ; fo r ( k=n ; k >0;k−−){ i=i d [ k ] ; f o r ( j=son [ i ] ; j ; j=bro [ j ] ) i f ( out1 [ j ]+ w e i g h t [ j ]>=out1 [ i ] ) { out2 [ i ]= out1 [ i ] ; out1 [ i ]= out1 [ j ]+ w e i g h t [ j ] ; son1 [ i ]= j ; } e l s e i f ( out1 [ j ]+ w e i g h t [ j ]> out2 [ i ] ) out2 [ i ]= out1 [ j ]+ w e i g h t [ j ] ; } fo r ( k=2;k<=n ; k++){ i=i d [ k ] ; i n [ i ] = 0 ; i f ( i n [ pnt [ i ]] > i n [ i ] ) i n [ i ]= i n [ pnt [ i ] ] ; i f ( i==son1 [ pnt [ i ] ] ) l=out2 [ pnt [ i ] ] ; e l s e l=out1 [ pnt [ i ] ] ; i f ( l >i n [ i ] ) i n [ i ]= l ; i n [ i ]+=w e i g h t [ i ] ; } } void d f s ( int node ) { fo r ( int j , i=nbs [ node ] ; i ; i=next [ i ] ) { j=v a l u e [ i ] ; i f ( j==pnt [ node ] ) continue ; pnt [ j ]= node ; bro [ j ]= son [ node ] ; son [ node ]= j ; d f s ( j ) ; } } void out ( ) { int maxh=−1, minh=n+1, i ; fo r ( i =1; i<=n ; i ++) { i f ( i n [ i ]< out1 [ i ] ) h [ i ]= out1 [ i ] ; e l s e h [ i ]= i n [ i ] ; i f ( h [ i ]>maxh ) maxh=h [ i ] ; i f ( h [ i ]<minh ) minh=h [ i ] ; } cout<<” Best Roots : ” ; fo r ( i =1; i<=n ; i ++) i f ( h [ i ]==minh ) cout<<” ”<<i ; cout<<e n d l <<”Worst Roots : ” ; fo r ( i =1; i<=n ; i ++) i f ( h [ i ]==maxh ) cout<<” ”<<i ; cout<<e n d l ; } int main ( ) { int i , j , k , l ; while ( c i n >>n ) { f o r ( i =1; i<=n ; i ++) out1 [ i ]= out2 [ i ]= son1 [ i ]= son [ i ]= bro [ i ]= pnt [ i ]= next [ i ]= nbs [ i ] = 0 ; f o r (num=1, i =1; i<=n ; i ++){ c i n >>l ; f o r ( k=0;k<l ; k++) { c i n >>j ; v a l u e [ num]= j ; next [ num]= nbs [ i ] ; nbs [ i ]=num++;} } d f s ( 1 ) ; s o l v e ( ) ; out ( ) ; } return 0 ; } 80 6.32 Minimum Cyclic Presentation int MinimumCyclicPresentation ( char ∗ s , int n ) { int i , j , x , y , u , v ; fo r ( x=0,y = 1 ; y<n ; y++) i f ( s [ y]<=s [ x ] ) { i=u=x ; j=v=y ; while ( s [ i ]==s [ j ] ) { ++u ; i f ( ++ i == n ) i =0; ++v ; i f ( ++ j == n ) j =0; i f ( i==x ) break ; } i f ( s [ i ]<=s [ j ] ) y = v ; e l s e { x = y ; i f ( u>y ) y = u ; } } return x ; } 81 6.33 Maximum Clique int l i s t [ maxn ] [ maxn ] , g [ maxn ] [ maxn ] , s [ maxn ] , d e g r e e [ maxn ] , b e h i d e [ maxn ] ; int found , n , curmax , c u r o b j ; void s o r t d e g r e e ( ) { fo r ( int j , k , l , i =1; i<=n ; i ++) { f o r ( k=i , j=i +1; j<=n ; j ++) i f ( d e g r e e [ j ]< d e g r e e [ k ] ) k=j ; i f ( k!= i ) { s t d : : swap ( d e g r e e [ i ] , d e g r e e [ k ] ) ; f o r ( l =1; l<=n ; l ++) s t d : : swap ( g [ i ] [ l ] , g [ k ] [ l ] ) ; f o r ( l =1; l<=n ; l ++) s t d : : swap ( g [ l ] [ i ] , g [ l ] [ k ] ) ; } } } void d f s ( int d ) { i f ( d−1>curmax ) { found =1; return ; } ; int i , j ; fo r ( i =1; i < l i s t [ d −1][0] − curmax+d ; i ++) i f ( ! found && d+b e h i d e [ l i s t [ d − 1 ] [ i ]+1] > curmax && ( l i s t [ d−1][0]== i | | d+b e h i d e [ l i s t [ d − 1 ] [ i +1]] > curmax ) ) { f o r ( j=i +1, l i s t [ d ] [ 0 ] = 0 ; j<=l i s t [ d − 1 ] [ 0 ] ; j ++) i f ( g [ l i s t [ d−1][ j ] ] [ l i s t [ d−1][ i ] ] ) l i s t [ d][++ l i s t [ d ] [ 0 ] ] = l i s t [ d − 1 ] [ j ] ; i f ( l i s t [ d ] [ 0 ] = = 0 | | d + b e h i d e [ l i s t [ d ] [ 1 ] ] > curmax ) d f s ( d +1); } } void s o l v e ( ) { s o r t d e g r e e ( ) ; b e h i d e [ n +1]=0; b e h i d e [ n ] = 1 ; fo r ( int j , i=n−1; i >0; i −−) { curmax=b e h i d e [ i + 1 ] ; found= l i s t [ 1 ] [ 0 ] = 0 ; f o r ( j=i +1; j<=n ; j ++) i f ( g [ j ] [ i ] ) l i s t [ 1 ] [ + + l i s t [ 1 ] [ 0 ] ] = j ; d f s ( 2 ) ; b e h i d e [ i ]=curmax+found ; } cout<<b e h i d e [1]<< e n d l ; } int main ( ) { int i , j ; while ( c i n >>n , n ) { f o r ( i =1; i<=n ; i ++) for ( j =1, d e g r e e [ i ] = 0 ; j<=n ; j ++) { c i n >> g [ i ] [ j ] ; d e g r e e [ i ]+=(g [ i ] [ j ] ! = 0 ) ; } solve ( ) ; } return 0 ; } 82 6.34 Maximal Non-Forbidden Submatrix #define f o r b i d d e n 1 int wx , wy , g [ maxn ] [ maxn ] , h [ maxn ] , r [ maxn ] , l [ maxn ] ; int s o l v e ( ) { int i , j , k , ans , l e f t , r i g h t ; ans = 0 ; memset ( h , 0 , s i z e o f ( h ) ) ; fo r ( i =0; i <wx ; i ++) { f o r ( j =0; j <wy ; j ++) i f ( g [ i ] [ j ] ! = f o r b i d d e n ) h [ j ]++; e l s e h [ j ] = 0 ; f o r ( j =0; j <wy ; j ++) i f ( h [ j ] ) { i f ( j = = 0 | | h [ j −1]==0) l e f t =j ; i f ( i = = 0 | | g [ i − 1 ] [ j ]== f o r b i d d e n ) l [ j ]= l e f t ; i f ( l e f t >l [ j ] ) l [ j ]= l e f t ; } f o r ( j=wy−1; j >=0; j −−) i f ( h [ j ] ) { i f ( j==wy − 1 | | h [ j +1]==0 ) r i g h t=j ; i f ( i = = 0 | | g [ i − 1 ] [ j ]== f o r b i d d e n ) r [ j ]= r i g h t ; i f ( r i g h t <r [ j ] ) r [ j ]= r i g h t ; } f o r ( j =0; j <wy ; j ++) i f ( ( r [ j ]− l [ j ]+1)∗ h [ j ] > ans ) ans = ( r [ j ]− l [ j ]+1)∗ h [ j ] ; } return ans ; } 6.35 Maximum Two Chain Problem typedef struct { int x , y ; } p o i n t ; int cmp( const void ∗ e1 , const void ∗ e2 ) { const p o i n t ∗ p1 = ( const p o i n t ∗ ) e1 ; const p o i n t ∗ p2 = ( const p o i n t ∗ ) e2 ; i f ( p1−>x ! = p2−>x ) return p1−>x − p2−>x ; return p1−>y − p2−>y ; } int n ; p o i n t p [MAX] ; void i n i t i a l i z e ( ) { int i ; for ( s c a n f ( ”%d” , & n ) , i = 1 ; i <= n ; i ++) s c a n f ( ”%d%d” , & p [ i ] . x , & p [ i ] . y ) ; q s o r t (&p [ 1 ] , n , s i z e o f ( p o i n t ) , cmp ) ; p [ 0 ] . x = p [ 0 ] . y = 0; } int deg [MAX] = { 0 } , queue [MAX] ; int maxlevel , l e v e l [MAX] = { 0 } ; int l e f t [MAX] = { 0 } , r i g h t [MAX] = { 0 } , mark [MAX] = { 0 } ; 83 void l o c a l c h a i n int i , j ; for ( i = 1 ; i for ( j = i if (p[ i deg [ () { <= n ; i ++) + 1 ; j <= n ; j ++) ] . y <= p [ j ] . y ) i ]++; for ( queue [ 0 ] = 0 , i = 1 ; i <= n ; i ++) i f ( deg [ i ] = = 0 ) queue[++queue [ 0 ] ] = i ; for ( i = 1 , m a x l e v e l = −1; i <= queue [ 0 ] ; i ++) f o r ( j = 1 ; j < queue [ i ] ; j ++) i f ( p [ j ] . y <= p [ queue [ i ] ] . y ) i f (−−deg [ j ] = = 0 ) { queue[++queue [ 0 ] ] = j , l e v e l [ j ] = l e v e l [ queue [ i ] ] + 1 ; i f ( l e v e l [ j ] > maxlevel ) maxlevel = l e v e l [ j ] ; } fo r ( m a x l e v e l ++, i = 1 ; i <= n ; i ++) l e v e l [ i ] = maxlevel − l e v e l [ i ] ; for ( mark [ 0 ] = n + 1 , i = 1 ; i <= n ; i ++) { f o r ( j = 0 ; j < i ; j ++) i f ( mark [ j ] && l e v e l [ j ] == l e v e l [ i ] − 1 && p [ j ] . y <= p [ i ] . y ) break ; if ( j < i ) { i f ( l e f t [ l e v e l [ i ] ] = = 0 ) l e f t [ l e v e l [ i ] ] = i , mark [ i ] = n + 1 ; mark [ r i g h t [ l e v e l [ i ] ] ] − − ; mark [ r i g h t [ l e v e l [ i ] ] = i ]++; } } } int i n d e x [MAX] , v a l u e [MAX] = { 0 } , l e v v a l u e [MAX] ; int index cmp ( const void ∗ e1 , const void ∗ e2 ) { return l e v e l [ ∗ ( const int ∗ ) e1 ] − l e v e l [ ∗ ( const int ∗ ) e2 ] ; } void c a l c v a l u e ( ) { int q , i , j , l e v ; fo r ( i = 1 ; i <= n ; i ++) index [ i ] = i ; q s o r t ( index , n , s i z e o f ( int ) , index cmp ) ; for ( q = 1 ; q <= n ; q++) { le v = l e v e l [ i = index [ q ] ] ; i f ( l e f t [ l e v ] == i && r i g h t [ l e v ] == i ) value [ i ] = levvalue [ lev − 1] + 1; e l s e i f ( l e f t [ l e v ] == i | | r i g h t [ l e v ] == i ) value [ i ] = levvalue [ lev − 1] + 2; else f o r ( j = 0 ; j < i ; j ++) { i f ( mark [ j ] ) v a l u e [ j ] = l e v v a l u e [ l e v e l [ j ] ] ; i f ( p [ j ] . y <= p [ i ] . y && v a l u e [ j ] + l e v e l [ i ] − l e v e l [ j ] + 1 > v a l u e [ i ] ) value [ i ] = value [ j ] + l e v e l [ i ] − l e v e l [ j ] + 1 ; } i f ( value [ i ] > levvalue [ lev ] ) levvalue [ lev ] = value [ i ] ; } } 84 void p u t a n s w e r ( ) { int i , max = 0 ; for ( i = 1 ; i <= n ; i ++) i f ( v a l u e [ i ] > max) max = v a l u e [ i ] ; p r i n t f ( ”%d\n” , max ) ; } void main ( ) { initialize (); local chain (); calc value (); put answer ( ) ; } 6.36 N Queens Problem int main ( ) { int n , i , odd ; while ( c i n >>n ) { i f ( n <4) cout<<” I m p o s s i b l e ” ; e l s e i f ( ( n/2)%3!=1){ cout <<2; f o r ( i = 4 ; i<=n ; i +=2) cout<<” ”<<i ; f o r ( i = 1 ; i<=n ; i +=2) cout<<” ”<<i ; } else { i f ( n & 1 ) { n−−; odd = 1 ; } e l s e odd =0; cout << n / 2 ; f o r ( i=n / 2 + 1 ; i !=n /2 −1; i =( i +2)%n ) cout<<” ”<<i +1; f o r ( i =( i+n−2)%n ; i !=n /2 −1; i =( i+n−2)%n ) cout<<” ”<<n−i ; cout<<” ”<<n−i ; i f ( odd ) cout<<” ”<<n+1; } cout<<e n d l ; } return 0 ; } 6.37 de Bruijn Sequence Generator int go[1<<maxn ] , s t a r t , now , n , k , a[(1<<maxn)+maxn ] , i , ans , c a s e n o ; int main ( ) { ifstream cin ( ” input . txt ” ) ; fo r ( c i n >>c a s e n o ; caseno − −;){ c i n >>n>>k ; memset ( go , 0 , s i z e o f ( go ) ) ; memset ( a , 0 , s i z e o f ( a ) ) ; now=s t a r t =(1<<(n −1)) −1; i =0; do { i f ( go [ now ] ) { a [ i ++]=1; now=(now∗2+1)& s t a r t ; } e l s e { go [ now ] = 1 ; a [ i ++]=0; now=(now∗2)& s t a r t ; } } while ( now!= s t a r t ) ; a [ i ++]=1; f o r ( i = 0 ; i <n ; i ++) a [ i +(1<<n )]= a [ i ] ; f o r ( ans=i = 0 ; i <n ; i ++) ans=ans∗2+a [ k+i ] ; cout<<ans<<e n d l ; } return 0 ; } 85 6.38 ZOJ 1482 Partition #define maxn 3 0 1 0 int n , pnt [ maxn ] , rank [ maxn ] ; int f i n d ( int x ) { i f ( x!= pnt [ x ] ) pnt [ x]= f i n d ( pnt [ x ] ) ; return pnt [ x ] ; } int main ( ) { int i , j , ans ( 0 ) , x ; c i n >> n ; memset ( pnt , 0 , s i z e o f ( pnt ) ) ; fo r ( i = 1 ; i<=n ; i ++) for ( j = 1 ; j<=n ; j ++){ c i n >>x ; i f ( ! x ){ i f ( pnt [ j ] ) pnt [ f i n d ( j )]= j ; i f ( pnt [ j −1]) pnt [ j −1]= j ; pnt [ j ]= j ; } e l s e { i f ( pnt [ j ]== j ) ans ++; pnt [ j ] = 0 ; } } fo r ( i = 1 ; i<=n ; i ++) i f ( pnt [ i ]== i ) ans++; cout<<ans<<e n d l ; return 0 ; } 86