Professional Documents
Culture Documents
Hao Yuan
Department of Computer Science and Engineering
Shanghai Jiaotong University
3 Number Theory 25
3.1 Greatest Common Divisor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.2 Chinese Remainder Theorem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.3 Prime Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.4 φ Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.5 Discrete Logarithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.6 Square Roots in Zp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4 Algebraic Algorithms 29
4.1 Linear Equations in Z2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.2 Linear Equations in Z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.3 Linear Equations in Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.4 Linear Equations in R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.5 Roots of Polynomial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1
4.6 Roots of Cubic and Quartic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.7 Fast Fourier Transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.8 FFT - Polynomial Multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.9 FFT - Convolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.10 FFT - Reverse Bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.11 Linear Programming - Primal Simplex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5 Computational Geometry 38
5.1 Basic Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.2 Extended Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.3 Convex Hull . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.4 Point Set Diameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.5 Closest Pair . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.6 Circles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.7 Largest Empty Convex Polygon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.8 Triangle Centers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.9 Polyhedron Volume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.10 Planar Graph Contour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.11 Rectangles Area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.12 Rectangles Perimeter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.13 Smallest Enclosing Circle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.14 Smallest Enclosing Ball . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6 Classic Problems 57
6.1 Bernoulli Number Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.2 Baltic OI’99 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
6.3 Bead Coloring — Pólya Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
6.4 Binary Stirling Number . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.5 Box Surface Distance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.6 Calculate Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.7 Cartesian Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
6.8 Catalan Number Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.9 Coloring Regular Polygon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
6.10 Counting Inverse Pairs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
6.11 Counting Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
6.12 Eight Puzzle Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
6.13 Extended Honai Tower . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
6.14 High Precision Square Root . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
6.15 Largest Empty Rectangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
6.16 Last Non-Zero Digit of N! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.17 Least Common Ancestor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.18 Longest Common Substring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
6.19 Longest Non Descending Sub Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
6.20 Join and Disjoin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
6.21 Magic Square . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.22 Optimal Binary Search Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
6.23 Pack Rectangles — Cut Rectangles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
6.24 Pack Rectangles — O(N 2 ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6.25 Parliament . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6.26 π Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6.27 Plant Trees — Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
6.28 Plant Trees — Segment Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
6.29 Range Maximum Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
6.30 Travelling Salesman Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
6.31 Tree Heights . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
6.32 Minimum Cyclic Presentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6.33 Maximum Clique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.34 Maximal Non-Forbidden Submatrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
6.35 Maximum Two Chain Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
6.36 N Queens Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
6.37 de Bruijn Sequence Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
6.38 ZOJ 1482 Partition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
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 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
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 −−;
}
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 ) ;
};
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 ) ;
}
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 ( ) ; }
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;
}
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 ;
}
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 ;
}
};
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 ;
}
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
void i n i t ( )
{ num= 0 ; bro [ num ] = 0 ; son [ num ] = 0 ; data [ 0 ] = − 1 ; }
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 ) ) ; }
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 ;
}
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.15 KMP
int f a i l [ maxlen ] ;
// 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;
}
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
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 ;
}
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 ]
}
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 ;
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 ] ;
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 ] ;
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 ; }
};
}
}
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 ) ;
}
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 ;
}
18
2.9 Maximum Flow — Ford Fulkson in Link
#define maxn 1 0 0 0
#define maxm 2 ∗ maxn∗maxn
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 ] ;
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;
}
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 ( )
{
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 ;
}
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 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 ;
}
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
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 ;
3.4 φ Generator
φ(n) = n p|n (1 − p1 ), where p is a prime.
Q
φ(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
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 ] ; }
27
3.6 Square Roots in Zp
#define l l o n g int64
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
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
P
// Gauss Elimination : 0≤j<nn ai,j xi,j = ai,nn
int m, nn , a [ maxn ] [ maxn ] ;
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 ;
}
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 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 ;
}
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 ;
}
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 ;
}
#define cp complex<double>
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 ;
}
\ \ 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 ;
}
struct cp { double re , im ; } ;
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 ) ;
}
}
// 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
#define OPTIMAL −1
#define UNBOUNDED −2
#define FEASIBLE −3
#define INFEASIBLE −4
#define PIVOT OK 1
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 ; c [0]=0;
f o r ( i = 1 ; i<=m; i ++){ for ( j = 1 ; j<=n ; j ++) c i n >>a [ i ] [ j ] ; c i n >>r h s [ i ] ; }
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 ] = %10 l f \n” , j , x [ j ] ) ;
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
Chapter 5
Computational Geometry
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 ) ;
}
// 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;
}
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 ;
}
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
41
Montone Chain, O(N log N )
42
Javis March, O(N H)
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 ;
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 ) ) ; }
5.6 Circles
Crossing of |P − P0 | = r and ax + by + c = 0
44
−−→
Crossing of |P − P0 | = r and P1 P2
45
5.7 Largest Empty Convex Polygon
#define ABS( x ) ( ( x ) >=0 ? ( x ) : − ( x ) )
#define CROSS( x1 , y1 , x2 , y2 ) ( ( x1 ) ∗ ( y2 )−( x2 ) ∗ ( y1 ) )
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
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 ] ;
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 ] ;
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 ; }
};
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 ++);
}
}
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 ) ; }
};
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 ++);
}
}
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 ) ; }
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 ;
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
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 ;
}
If L is odd ,
L
1 L+1 X
f (C, L) = (LC 2 + C (K,L) )
2L
K=1
If L is even,
L
1 L L L
X
f (C, L) = ( (C 2 + C 2 +1 ) + C (K,L) )
2L 2
K=1
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
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 ;
}
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 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 ) ) ) ;
}
60
6.8 Catalan Number Generator
#define maxn 1 0 0 0
#define maxlen 7 0 0
#define maxpnum 4 0 0
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 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 ;
}
#define maxn 1 0 0 0 0
int a [ maxn ] , t [ maxn ] , n , ans ;
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 ;
}
}
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} };
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 ;
}
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 ;
}
int s t e p , d i [ s i z e ] ;
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 ;
}
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 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 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 <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 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 [ j ]] > l a s t )
{
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 [ j ];
i f ( y [ j ]<=y [ i ] && y [ j ]> low ) low = y [ j ];
}
}
cout<<ans<<e n d l ;
return 0 ;
}
68
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 ;
}
int a [ 1 0 ] = { 6 , 1 , 2 , 6 , 4 , 4 , 4 , 8 , 4 , 6 } ;
int b [ 4 ] = { 1 , 8 , 4 , 2 } ;
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 ;
}
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 ] ] ;
}
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 ; } ;
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
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
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 ;
}
73
6.21 Magic Square
#define maxn 1 0 0 0
int a [ maxn ] [ maxn ] , n ;
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 [ i ] [ i ]= i ;
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 ] [ j ] = h [ i ] [ k−1]+h [ k + 1 ] [ j ]+ s [ i ] [ j ]−a [ k ] ;
kk [ i ] [ j ] = k ;
}
}
}
return h [ 1 ] [ n ] ;
}
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 ;
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 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 ;
}
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 ;
}
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 ] ;
}
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 ;
}
}
78
6.30 Travelling Salesman Problem
int n , x [ maxn ] , y [ maxn ] , i d [ maxn ] ;
double g [ maxn ] [ maxn ] ;
double s o l v e ( )
{
int i , j , k , l , l o o p ;
double cur , ans=1e30 ;
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);
}
};
i f ( cur<ans ) ans=c u r ;
}
}
return ans ;
}
79
6.31 Tree Heights
#define maxn 5 0 0 3 ∗ 4
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 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 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 ;
}
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;
}
83
void l o c a l c h a i n () {
int i , j ;
for ( i = 1 ; i <= n ; i ++)
for ( j = i + 1 ; j <= n ; j ++)
if (p[ i ] . y <= p [ j ] . y )
deg [ i ]++;
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 ) ;
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 ;
}
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 ( ) ;
}
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 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