100% found this document useful (1 vote)
226 views30 pages

Icpc Reference

Uploaded by

pingpong player
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
226 views30 pages

Icpc Reference

Uploaded by

pingpong player
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

ICPC References

Leo Lee, Soumyaditya Choudhuri, Yusuf Onur Usumez


20th October 2023

Listings
articulation.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
cht–aliens–wqs.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
cht–monotonic.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
cht–norestriction.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
dijkstra.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
fenwick.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
fenwick–rangeupdate.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
floyd.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
geometry.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
lca.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
pbds.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
persistent–segtree.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
qexp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
scc–mice.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
segtree.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
segtree–lazy.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
segtree–lazy–progression.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
segtree–lazy–sum.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
sieve.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
smjleo–template.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
suffix–array.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
trie–xor.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
ufds.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
ufds–rank.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
wavelet.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

1
1 articulation.cpp
// code f o r bombing2
// f i n d i n g a r t i c u l a t i o n p o i n t s
// whats t h e max number o f r e s u l t i n g components ?

#include ” b i t s / s t d c ++.h”
using namespace s t d ;
#define int long long

const int MXN = 2 0 0 0 0 5 ;


int n , m;
v e c t o r <int> a d j [MXN] ;

int ans = 0 ;
int depth [MXN] ;
int mdep [MXN] ;
bool v i s [MXN] ;

void d f s ( int no , int pa , int dep ) {


depth [ no ] = dep ;
int mno = dep ;
v i s [ no ] = true ;
int comp = ( pa == −1 ? 0 : 1 ) ;
f o r ( auto o t : a d j [ no ] ) {
i f ( o t == pa ) continue ;
i f ( v i s [ ot ] ) {
// a n c e s t o r
mno = min (mno , depth [ o t ] ) ;
}
else {
d f s ( ot , no , dep+1) ;
i f ( mdep [ o t ] >= dep ) {
// new comp
comp++;
}
else {
// c o n n e c t s o v e r i t
mno = min (mno , mdep [ o t ] ) ;
}
}
}
ans = max( ans , comp ) ;
mdep [ no ] = mno ;
}

signed main ( ) {

i o s b a s e : : s y n c w i t h s t d i o ( f a l s e ) ; c i n . t i e (NULL) ; c o u t . t i e (NULL) ;

c i n >> n >> m;
f o r ( int i =0; i <m; i ++) {
int a , b ;
c i n >> a >> b ;
a d j [ a ] . push back ( b ) ;
a d j [ b ] . push back ( a ) ;
}

2
d f s ( 0 , −1, 0 ) ;

c o u t << ans << e n d l ;

2 cht-aliens-wqs.cpp

// WQS / A l i e n s t r i c k code

p a i r <int , int> s o l v e ( int c o s t ) {


// c o u t << ” t r y c o s t : ” << c o s t << e n d l ;
// assumes t h a t s o l v e i s a f u n c t i o n t h a t w i l l r e t u r n a p a i r :
// − { answer AFTER num p h o t o s a d j u s t m e n t , num p h o t o s }
}

// a l i e n s b i t
long long t a k e p h o t o s ( signed N, signed m, signed k , s t d : : v e c t o r <signed> r ,
s t d : : v e c t o r <signed> c ) {

int low = 0 ; // must be b e l o w answer


int h i g h = ( long long ) m ∗ m + 1 0 ; // must be ab o ve answer

// t r y w i t h b i n s e a r c h

while ( low <= h i g h ) {


// c o u t << ’ ’ << low << ’ ’ << h i g h << e n d l ;
int mid = ( low + h i g h ) / 2 ;
auto h e r e = s o l v e ( mid ) ;
i f ( h e r e . s e c o n d == k ) {
return h e r e . f i r s t ;
}
i f ( here . second > k ) {
low = mid + 1 ;
}
else {
h i g h = mid − 1 ;
}
}

// a t t h i s p o i n t , no e x a c t e x i s t s

i f ( low == −1) {
return s o l v e ( h i g h ) . f i r s t ;
}
i f ( h i g h == −1) {
return s o l v e ( low ) . f i r s t ;
}

auto withlow = s o l v e ( low ) ;


auto w i t h h i g h = s o l v e ( h i g h ) ;

int x1 = withlow . second , y1 = withlow . f i r s t ;

3
int x2 = w i t h h i g h . second , y2 = w i t h h i g h . f i r s t ;

// l i n e a r r e c t i f i c a t i o n

return y1 + ( y2 − y1 ) ∗ ( k − x1 ) / ( x2 − x1 ) ;

#undef int

3 cht-monotonic.cpp
// t h i s i s a c t u a l l y NOI 2020 d i s c h a r g i n g code

int n ;
const int MXN = 1 0 0 0 0 0 5 ;
int t [MXN] , dp [MXN] ;

struct Li ne {
int a , b ;
Li ne ( int m, int c ) {
a = m;
b = c;
}
int v a l u e ( int x ) {
return a ∗ x + b ;
}
};

// d e s c e n d i n g h u l l

// MIN convex h u l l , i n s e r t s must be i n d e c r e a s i n g g r a d i e n t


/∗

do you need a max h u l l ?


− i n s e r t l i n e s w i t h −m and −c
− q u e r y x as normal
− t h e a c t u a l answer i s n e g a t i v e o f q u e r y answer
∗/
struct CHT {
v e c t o r <Line> h u l l ;

int c u r r ;

CHT( ) {
curr = 0;
}

void addLine ( Li ne c ) {

4
while ( h u l l . s i z e ( ) >= 2 ) {
Li ne a = h u l l [ h u l l . s i z e ( ) −2];
Li ne b = h u l l . back ( ) ;
// i f ( x i n t e r ( a , b ) >= x i n t e r ( b , c ) ) {
int128 l = (b . b − a . b) ;
int128 m = b. a − c . a ;
int128 e = ( c . b − b . b) ;
int128 f = a . a − b. a ;
i f ( l ∗ m >= e ∗ f ) {
h u l l . pop back ( ) ;
}
else {
break ;
}
}
h u l l . push back ( c ) ;
}

int query ( int x ) {

int low = 0 ;
int h i g h = h u l l . s i z e ( ) − 1 ;

while ( low < h i g h ) {


int mid = ( low + h i g h ) / 2 ;
int v1 = h u l l [ mid ] . v a l u e ( x ) ;
int v2 = h u l l [ mid + 1 ] . v a l u e ( x ) ;
i f ( v1 < v2 ) {
h i g h = mid ;
}
else {
low = mid + 1 ;
}
}
return h u l l [ low ] . v a l u e ( x ) ;

int querymono ( int x ) {


i f ( h u l l . empty ( ) ) return LLONG MAX / 2 ;
c u r r = min ( c u r r , ( int ) h u l l . s i z e ( ) −1) ;

while ( c u r r + 1 < h u l l . s i z e ( ) && l i n e s [ h u l l [ c u r r ] ] . v a l u e ( x ) > l i n e s


[ h u l l [ c u r r + 1 ] ] . v a l u e ( x ) ) c u r r ++;

return l i n e s [ h u l l [ c u r r ] ] . v a l u e ( x ) ;
}

} cht ;

signed main ( ) {

// ran ( ) ; f a s t ( ) ;

c i n >> n ;
f o r ( int i =1; i<=n ; i ++) {
c i n >> t [ i ] ;
t [ i ] = max( t [ i ] , t [ i −1]) ;

5
}

f o r ( int i =1; i<=n ; i ++) {


dp [ i ] = t [ i ] ∗ ( i + ( n − i ) ) ;
c h t . addLine ( L ine (− i , dp [ i −1]) ) ;
i f ( i > 1 ) dp [ i ] = min ( dp [ i ] , t [ i ] ∗ ( n + 1 ) + c h t . query ( t [ i ] ) ) ;

c o u t << dp [ n ] << e n d l ;

4 cht-norestriction.cpp
// CHT w i t h no r e s t r i c t i o n s

// Keeps upper h u l l f o r maximums .


// add l i n e s w i t h −m and −b and r e t u r n −ans t o
// make t h i s code w o r k i n g f o r minimums .
// ( btw t h e r e ’ s a chtDynamicMin under t h i s which d o e s e x a c t l y t h a t )

#define l l long long


typedef long double l d ;
const l d i n f = 1 e18 ;

struct chtDynamic {
struct l i n e {
l l m, b ; l d x ;
l l v a l ; bool i s Q u e r y ;
l i n e ( l l m = 0 , l l b = 0) {
m = m;
b = b;
val = 0;
x = −i n f ;
isQuery = false ;
}

l l e v a l ( l l x ) const { return m ∗ x + b ; }
bool p a r a l l e l ( const l i n e &l ) const { return m == l .m; }
l d i n t e r s e c t ( const l i n e &l ) const {
return p a r a l l e l ( l ) ? i n f : 1 . 0 ∗ ( l . b − b ) / (m − l .m) ;
}
bool operator < ( const l i n e &l ) const {
i f ( l . i s Q u e r y ) return x < l . v a l ;
e l s e return m < l .m;
}
};

s e t <l i n e > h u l l ;
typedef s e t <l i n e > : : i t e r a t o r i t e r ;

bool cPrev ( i t e r i t ) { return i t != h u l l . b e g i n ( ) ; }


bool cNext ( i t e r i t ) { return i t != h u l l . end ( ) && next ( i t ) != h u l l . end ( )
; }

6
bool bad ( const l i n e &l 1 , const l i n e &l 2 , const l i n e &l 3 ) {
return l 1 . i n t e r s e c t ( l 3 ) <= l 1 . i n t e r s e c t ( l 2 ) ;
}
bool bad ( i t e r i t ) {
return cPrev ( i t ) && cNext ( i t ) && bad ( ∗ prev ( i t ) , ∗ i t , ∗ next ( i t ) ) ;
}

i t e r update ( i t e r i t ) {
i f ( ! cPrev ( i t ) ) return i t ;
l d x = i t −> i n t e r s e c t ( ∗ prev ( i t ) ) ;
l i n e tmp ( ∗ i t ) ; tmp . x = x ;
it = hull . erase ( it ) ;
return h u l l . i n s e r t ( i t , tmp ) ;
}

void addLine ( l l m, l l b ) {
l i n e l (m, b ) ;
i t e r i t = h u l l . lower bound ( l ) ;
i f ( i t != h u l l . end ( ) && l . p a r a l l e l ( ∗ i t ) ) {
i f ( i t −> b < b ) i t = h u l l . e r a s e ( i t ) ;
e l s e return ;
}

i t = hull . insert ( it , l ) ;
i f ( bad ( i t ) ) return ( void ) h u l l . e r a s e ( i t ) ;

while ( cPrev ( i t ) && bad ( prev ( i t ) ) ) h u l l . e r a s e ( prev ( i t ) ) ;


while ( cNext ( i t ) && bad ( next ( i t ) ) ) h u l l . e r a s e ( next ( i t ) ) ;

i t = update ( i t ) ;
i f ( cPrev ( i t ) ) update ( prev ( i t ) ) ;
i f ( cNext ( i t ) ) update ( next ( i t ) ) ;
}

l l query ( l l x ) const {
if ( hull . empty ( ) ) return − i n f ;
line q; q . val = x , q . isQuery = 1 ;
iter it = −−h u l l . lower bound ( q ) ;
return i t −> e v a l ( x ) ;
}
} ds ;

#define l l long long


typedef long double l d ;
const l d i n f = 1 e18 ;

struct chtDynamicMin {
struct l i n e {
l l m, b ; l d x ;
l l v a l ; bool i s Q u e r y ;
l i n e ( l l m = 0 , l l b = 0) {
m = m;
b = b;
val = 0;
x = −i n f ;
isQuery = false ;
}

7
l l e v a l ( l l x ) const { return m ∗ x + b ; }
bool p a r a l l e l ( const l i n e &l ) const { return m == l .m; }
l d i n t e r s e c t ( const l i n e &l ) const {
return p a r a l l e l ( l ) ? i n f : 1 . 0 ∗ ( l . b − b ) / (m − l .m) ;
}
bool operator < ( const l i n e &l ) const {
i f ( l . i s Q u e r y ) return x < l . v a l ;
e l s e return m < l .m;
}
};

s e t <l i n e > h u l l ;
typedef s e t <l i n e > : : i t e r a t o r i t e r ;

bool cPrev ( i t e r i t ) { return i t != h u l l . b e g i n ( ) ; }


bool cNext ( i t e r i t ) { return i t != h u l l . end ( ) && next ( i t ) != h u l l . end ( )
; }

bool bad ( const l i n e &l 1 , const l i n e &l 2 , const l i n e &l 3 ) {


return l 1 . i n t e r s e c t ( l 3 ) <= l 1 . i n t e r s e c t ( l 2 ) ;
}
bool bad ( i t e r i t ) {
return cPrev ( i t ) && cNext ( i t ) && bad ( ∗ prev ( i t ) , ∗ i t , ∗ next ( i t ) ) ;
}

i t e r update ( i t e r i t ) {
i f ( ! cPrev ( i t ) ) return i t ;
l d x = i t −> i n t e r s e c t ( ∗ prev ( i t ) ) ;
l i n e tmp ( ∗ i t ) ; tmp . x = x ;
it = hull . erase ( it ) ;
return h u l l . i n s e r t ( i t , tmp ) ;
}

void addLine ( l l m, l l b ) {
m ∗= −1;
b ∗= −1;
l i n e l (m, b ) ;
i t e r i t = h u l l . lower bound ( l ) ;
i f ( i t != h u l l . end ( ) && l . p a r a l l e l ( ∗ i t ) ) {
i f ( i t −> b < b ) i t = h u l l . e r a s e ( i t ) ;
e l s e return ;
}

i t = hull . insert ( it , l ) ;
i f ( bad ( i t ) ) return ( void ) h u l l . e r a s e ( i t ) ;

while ( cPrev ( i t ) && bad ( prev ( i t ) ) ) h u l l . e r a s e ( prev ( i t ) ) ;


while ( cNext ( i t ) && bad ( next ( i t ) ) ) h u l l . e r a s e ( next ( i t ) ) ;

i t = update ( i t ) ;
i f ( cPrev ( i t ) ) update ( prev ( i t ) ) ;
i f ( cNext ( i t ) ) update ( next ( i t ) ) ;
}

l l query ( l l x ) const {
i f ( h u l l . empty ( ) ) return i n f ;
l i n e q ; q . val = x , q . isQuery = 1 ;

8
i t e r i t = −−h u l l . lower bound ( q ) ;
return − i t −> e v a l ( x ) ;
}
} dsmin ;

5 dijkstra.cpp
v e c t o r < p a i r <int , int> > a d j L i s t [N ] ; // p a i r . f i r s t i s t h e node , p a i r . second
i s the edge weight
int d i s t [N ] ;
p r i o r i t y q u e u e < p a i r <int , int >, v e c t o r < p a i r <int , int> >, g r e a t e r <> > pq ;

f o r ( int i =0; i <N; i ++) d i s t [ i ] = INT MAX ; // u n r e a c h a b l e ( i n f i n i t y )

dist [S] = 0;
pq . push ( m a k e p a i r ( 0 , S ) ) ;

while ( ! pq . empty ( ) ) {
auto c u r = pq . top ( ) ;
pq . pop ( ) ;

int x = c u r . second , d = c u r . f i r s t ;
i f ( d > d i s t [ x ] ) continue ;

f o r ( auto i t : a d j L i s t [ x ] ) {
int nx = i t . f i r s t , nd = d+i t . s e c o n d ;
i f ( d i s t [ nx ] <= nd ) continue ;
d i s t [ nx ] = nd ;
pq . push ( { nd , nx } ) ;
}
}

6 fenwick.cpp
int fw [N ] ;

void update ( int x , int v ) {


f o r ( ; x<N; x+=x&(−x ) ) fw [ x ] += v ;
}

int sum ( int x ) {


i f ( x == 0 ) return 0 ;
int r e s = 0 ;
f o r ( ; x ; x−=x&(−x ) ) r e s += fw [ x ] ;
return r e s ;
}

int range sum ( int a , int b ) { // i n c l u s i v e


// sum o f [ a , b ] , a <= b
return sum ( b ) − sum ( a −1) ;
}

// f e n w i c k t r e e i s 1−i n d e x e d

9
7 fenwick-rangeupdate.cpp
int fw [N] , fw2 [N ] ;

void update ( int x , int y , int v ) { // i n c l u s i v e


f o r ( int tx=x ; tx < N; tx += tx&(−tx ) ) fw [ tx ] += v , fw2 [ tx ] −= v ∗ ( x−1) ;
f o r ( int ty=y+1; ty < N; ty += ty&(−ty ) ) fw [ ty ] −= v , fw2 [ ty ] += v∗y ;
}

int sum ( int x ) {


int r e s = 0 ;
f o r ( int tx=x ; tx ; tx −= tx&(−tx ) ) r e s += fw [ tx ] ∗ x + fw2 [ tx ] ;
return r e s ;
}

int range sum ( int x , int y ) { // i n c l u s i v e


return sum ( y )−sum ( x−1) ;
}

// u s i n g two f e n w i c k s t o s i m u l a t e range u p d a t e range q u e r y i n l o g N

8 floyd.cpp
int adjMat [N ] [ N ] ;
// a d j a c e n c y matrix , s e t i t t o INT MAX i f e d g e doesn ’ t e x i s t

f o r ( int k = 0 ; k < N; ++k ) {


f o r ( int i = 0 ; i < N; ++i ) {
f o r ( int j = 0 ; j < N; ++j ) {
adjMat [ i ] [ j ] = min ( adjMat [ i ] [ j ] , adjMat [ i ] [ k ] + adjMat [ k ] [ j ] ) ;
}
}
}

9 geometry.cpp
#include <b i t s / s t d c ++.h>
using namespace s t d ;
using l l = long long ;

template <c l a s s T> int sgn (T x ) { return ( x > 0 ) − ( x < 0 ) ; }

template<c l a s s T>
struct P oi nt {
typedef P oi nt P ;
T x, y;
e x p l i c i t P oi nt (T x=0, T y=0) : x ( x ) , y ( y ) {}
bool operator <(P p ) const { return t i e ( x , y ) < t i e ( p . x , p . y ) ; }
bool operator==(P p ) const { return t i e ( x , y )==t i e ( p . x , p . y ) ; }
P operator+(P p ) const { return P( x+p . x , y+p . y ) ; }
P operator −(P p ) const { return P( x−p . x , y−p . y ) ; }
P operator ∗ (T d ) const { return P( x∗d , y∗d ) ; }
P operator / (T d ) const { return P( x/d , y/d ) ; }
T dot (P p ) const { return x∗p . x + y∗p . y ; }

10
T c r o s s (P p ) const { return x∗p . y − y∗p . x ; }
T c r o s s (P a , P b ) const { return ( a−∗t h i s ) . c r o s s ( b−∗t h i s ) ; }

T d i s t 2 ( ) const { return x∗x + y∗y ; }


double d i s t ( ) const { return s q r t ( ( double ) d i s t 2 ( ) ) ; }
// a n g l e t o x−a x i s i n i n t e r v a l [− pi , p i ]
double a n g l e ( ) const { return atan2 ( y , x ) ; }
P u n i t ( ) const { return ∗ t h i s / d i s t ( ) ; } // makes d i s t ( ) =1
P perp ( ) const { return P(−y , x ) ; } // r o t a t e s +90 d e g r e e s
P normal ( ) const { return perp ( ) . u n i t ( ) ; }
// r e t u r n s p o i n t r o t a t e d ’ a ’ r a d i a n s ccw around t h e o r i g i n
P r o t a t e ( double a ) const {
return P( x∗ c o s ( a )−y∗ s i n ( a ) , x∗ s i n ( a )+y∗ c o s ( a ) ) ; }
friend ostream& operator<<(ostream& os , P p ) {
return o s << ” ( ” << p . x << ” , ” << p . y << ” ) ” ; }
};

typedef Point<l l > P ; // change f o r o t h e r t y p e s

v e c t o r <P> c o n v e x H u l l ( v e c t o r <P> p t s ) {
i f ( ( int ) p t s . s i z e ( ) <= 1 ) return p t s ;
s o r t ( p t s . b e g i n ( ) , p t s . end ( ) ) ;
v e c t o r <P> h ( p t s . s i z e ( ) +1) ;
int s = 0 , t = 0 ;
f o r ( int i t = 2 ; i t −−; s = −−t , r e v e r s e ( p t s . b e g i n ( ) , p t s . end ( ) ) )
f o r (P p : p t s ) {
while ( t >= s + 2 && h [ t − 2 ] . c r o s s ( h [ t −1] , p ) <= 0 ) t −−;
h [ t++] = p ;
}
return {h . b e g i n ( ) , h . b e g i n ( ) + t − ( t == 2 && h [ 0 ] == h [ 1 ] ) } ;
}

// g i v e n t h e l i n e s−>e , f i n d where p s t a n d s
template<c l a s s P>
int s i d e O f (P s , P e , P p ) { return sgn ( s . c r o s s ( e , p ) ) ; }

// g i v e n t h e l i n e segment s−>e , f i n d w h e t h e r p i s on i t
template<c l a s s P> bool onSegment (P s , P e , P p ) {
return p . c r o s s ( s , e ) == 0 && ( s − p ) . dot ( e − p ) <= 0 ;
}

// g i v e n a convex p o l y g o n ( ccw o r d e r ) , t e s t w h e t h e r p i s i n i t
bool i n H u l l ( const v e c t o r <P>& l , P p , bool s t r i c t = true ) {
int a = 1 , b = l . s i z e ( ) − 1 , r = ! s t r i c t ;
i f ( ( int ) l . s i z e ( ) < 3 ) return r && onSegment ( l [ 0 ] , l . back ( ) , p ) ;
i f ( s i d e O f ( l [ 0 ] , l [ a ] , l [ b ] ) > 0 ) swap ( a , b ) ;
i f ( s i d e O f ( l [ 0 ] , l [ a ] , p ) >= r | | s i d e O f ( l [ 0 ] , l [ b ] , p )<= −r )
return f a l s e ;
while ( abs ( a − b ) > 1 ) {
int c = ( a + b ) / 2 ;
( sideOf ( l [ 0 ] , l [ c ] , p) > 0 ? b : a) = c ;
}
return sgn ( l [ a ] . c r o s s ( l [ b ] , p ) ) < r ;
}

int main ( ) {
ios base : : sync with stdio ( false ) ; cin . t i e ( nullptr ) ;

11
}

10 lca.cpp
const int N = 1 0 0 0 5 0 ;
const int LOGN = 1 7 ; // l o g 2 (MAXN)
int p [LOGN+ 1 ] [N] , h [N ] ; // h : h e i g h t
long long d [N ] ; // d i s t : sum o f e d g e w e i g h t from r o o t
v e c t o r <p a i r <int , int> > a d j L i s t [N ] ; // node , w e i g h t
b i t s e t <N> v i s i t e d ;

void d f s ( int x ) {
i f ( v i s i t e d [ x ] ) return ;
visited [ x ] = 1;
f o r ( int k = 0 ; k < LOGN; ++k ) {
i f ( p [ k ] [ x ] == −1) break ;
p [ k +1][ x ] = p [ k ] [ p [ k ] [ x ] ] ;
}
f o r ( auto i t : a d j L i s t [ x ] ) {
i f ( v i s i t e d [ i t . f i r s t ] ) continue ;
p [0][ it . first ] = x;
d [ i t . f i r s t ] = d [ x ] + i t . second ;
h[ it . f i r s t ] = h[ x ] + 1;
dfs ( i t . f i r s t ) ;
}
}

int l c a ( int a , int b ) {


i f ( h [ a ] > h [ b ] ) swap ( a , b ) ;

/∗ advance b by h [ b ] − h [ a ] p a r e n t s ∗/
f o r ( int k = 0 , d = h [ b ] − h [ a ] ; k < LOGN; ++k ) {
i f ( d & (1<<k ) ) b = p [ k ] [ b ] ;
}
i f ( a == b ) return a ;
a s s e r t ( h [ a ] == h [ b ] ) ; // same h e i g h t

f o r ( int k = LOGN−1; k >= 0 ; −−k ) {


i f ( p [ k ] [ a ] != p [ k ] [ b ] )
a = p[k ][ a] , b = p[k ][b];
}
a s s e r t ( p [ 0 ] [ a ] == p [ 0 ] [ b ] ) ; // same immediate p a r e n t
return p [ 0 ] [ a ] ;
}

11 pbds.cpp
#include <b i t s / s t d c ++.h>
#include <b i t s / e x t c ++.h>
using namespace s t d ;
using namespace gnu pbds ;

template <typename T>


using p b d s s e t = t r e e <T, n u l l t y p e , l e s s <T>, r b t r e e t a g ,
t r e e o r d e r s t a t i s t i c s n o d e u p d a t e >;

12
template <typename K, typename V>
using pbds map = t r e e <K, V, l e s s <K>, r b t r e e t a g ,
t r e e o r d e r s t a t i s t i c s n o d e u p d a t e >;

// same methods as s e t and map , e x c e p t w i t h two e x t r a f u n c t i o n s :


// f i n d b y o r d e r ( x ) : i t e r a t o r p o i n t i n g t o t h e x t h e l e m e n t i n t h e s e t (0−
indexed )
// o r d e r o f k e y ( k ) : g i v e s you t h e o r d e r o f t h e key k as i f i t was i n s e r t e d
i n t o t h e s e t (0− i n d e x e d )
// t h e y ’ r e b o t h somewhere b e t w e e n O( l o g n ) and O( l o g ˆ2 n ) on a v e r a g e

12 persistent-segtree.cpp
#include <b i t s / s t d c ++.h>
using namespace s t d ;
using l l = long long ;

struct Vertex {
Vertex ∗ l , ∗ r ;
int sum ;

Vertex ( int v a l ) : l ( n u l l p t r ) , r ( n u l l p t r ) , sum ( v a l ) {}


Vertex ( Vertex ∗ l , Vertex ∗ r ) : l ( l ) , r ( r ) , sum ( 0 ) {
i f ( l ) sum += l −>sum ;
i f ( r ) sum += r−>sum ;
}
};

Vertex ∗ b u i l d ( int a [ ] , int t l , int t r ) {


i f ( t l == t r )
return new Vertex ( a [ t l ] ) ;
int tm = ( t l + t r ) / 2 ;
return new Vertex ( b u i l d ( a , t l , tm) , b u i l d ( a , tm+1, t r ) ) ;
}

int get sum ( Vertex ∗ v , int t l , int t r , int l , int r ) {


if ( l > r)
return 0 ;
i f ( l == t l && t r == r )
return v−>sum ;
int tm = ( t l + t r ) / 2 ;
return get sum ( v−>l , t l , tm , l , min ( r , tm) )
+ get sum ( v−>r , tm+1, t r , max( l , tm+1) , r ) ;
}

Vertex ∗ update ( Vertex ∗ v , int t l , int t r , int pos , int n e w v a l ) {


i f ( t l == t r )
return new Vertex ( n e w v a l ) ;
int tm = ( t l + t r ) / 2 ;
i f ( pos <= tm)
return new Vertex ( update ( v−>l , t l , tm , pos , n e w v a l ) , v−>r ) ;
else
return new Vertex ( v−>l , update ( v−>r , tm+1, t r , pos , n e w v a l ) ) ;
}

int main ( ) {

13
ios base : : sync with stdio ( false ) ; cin . t i e ( nullptr ) ;

13 qexp.cpp
// AˆB mod M, M <= ( 2 ˆ 3 1 )−1

int qexp ( int A, int B, int M) {


i f (B == 0 ) return 1 ;
long long h a l f = qexp (A, B/ 2 , M) ;
h a l f ∗= h a l f ;
h a l f %= M;
i f (B%2) h a l f ∗= A;
return h a l f%M;
}

14 scc-mice.cpp
// code f i n d s s c c
// s t o r e s i n u f d s
// b e s t ( ) and a l l i s j u s t dp e x t e n s i o n , t h i s i s s o l v i n g f o r p a r t i c u l a r
problem

#include ” b i t s / s t d c ++.h”
using namespace s t d ;

int n , e ;
const int MXN = 1 0 0 0 0 5 ;
v e c t o r <int> a d j [MXN] , i n v [MXN] , ng [MXN] ;
s t a c k <int> p r o c ;
bool v i s [MXN] ;

int mo [MXN] ;
int comp [MXN] ;

int par [MXN] ;

void s e t u p ( ) {
f o r ( int i =0; i <MXN; i ++) par [ i ] = i ;
}

int p a r e n t ( int n ) {
i f ( n == par [ n ] ) return n ;
return par [ n ] = p a r e n t ( par [ n ] ) ;
}

void merge ( int a , int b ) {


int ax = p a r e n t ( a ) ;
int bx = p a r e n t ( b ) ;
i f ( ax == bx ) return ;
par [ ax ] = bx ;
mo [ bx ] += mo [ ax ] ;
}

14
void d f s ( int node ) {
i f ( ! v i s [ node ] ) {
v i s [ node ] = true ;
f o r ( int i =0; i <a d j [ node ] . s i z e ( ) ; i ++) {
i f ( ! v i s [ a d j [ node ] [ i ] ] ) d f s ( a d j [ node ] [ i ] ) ;
}
p r o c . push ( node ) ;
}
}

void a s s i g n ( int node , int t o ) {


i f ( comp [ node ] == −1) {
comp [ node ] = t o ;
merge ( node , t o ) ;
f o r ( int i =0; i <i n v [ node ] . s i z e ( ) ; i ++) {
a s s i g n ( i n v [ node ] [ i ] , t o ) ;
}
}
}

int s c o [MXN] ;

int b e s t ( int n ) {
i f ( s c o [ n ] != −1) return s c o [ n ] ;
int a = 0 ;
f o r ( int i =0; i <ng [ n ] . s i z e ( ) ; i ++) {
a = max( a , b e s t ( ng [ n ] [ i ] ) ) ;
}
return s c o [ n ] = a + mo [ n ] ;
}

int main ( ) {

f o r ( int i =0; i <MXN; i ++) s c o [ i ] = comp [ i ] = −1;


setup () ;

c i n >> n >> e ;

f o r ( int i =0; i <n ; i ++) c i n >> mo [ i ] ;

v e c t o r <p a i r <int , int> > f ;

f o r ( int i =0; i <e ; i ++) {


int a , b ;
c i n >> a >> b ;
a d j [ a ] . push back ( b ) ;
i n v [ b ] . push back ( a ) ;
f . push back ( m a k e p a i r ( a , b ) ) ;
}

f o r ( int i =0; i <n ; i ++) d f s ( i ) ;

while ( ! p r o c . empty ( ) ) {
int a = p r o c . top ( ) ;
p r o c . pop ( ) ;
assign (a , a) ;
}

15
f o r ( int i =0; i <e ; i ++) {
i f ( p a r e n t ( f [ i ] . f i r s t ) != p a r e n t ( f [ i ] . s e c o n d ) ) {
// c o u t << p a r e n t ( f [ i ] . f i r s t ) << ’ > ’ << p a r e n t ( f [ i ] . second ) <<
endl ;
ng [ p a r e n t ( f [ i ] . f i r s t ) ] . push back ( p a r e n t ( f [ i ] . s e c o n d ) ) ;
}
}

// end o f SCC s t u f f , have c o n s t r u c t e d compressed graph even

// f o r ( i n t i =0; i <n ; i ++) c o u t << i << ’ ’ << p a r e n t ( i ) << e n d l ;

c o u t << b e s t ( p a r e n t ( 0 ) ) << e n d l ;

15 segtree.cpp
template<typename T>
struct s e g t r e e {
// r o o t node i s a t 1 , node k has nodes 2 k and 2 k+1 as c h i l d r e n
T t r a n s (T i , T j ) {
// t r a n s i t i o n , change i f r e q u i r e d
return i + j ;
}

T∗ t r e e ;
int l e n ;

s e g t r e e ( int l e n g t h ) { // b u i l d t h e t r e e
len = length ;
t r e e = new T[ 2 ∗ l e n ] ;
f o r ( int i = l e n ; i < 2∗ l e n ; i ++) t r e e [ i ] = 0 ; // d e f a u l t v a l u e ,
change i f r e q u i r e d
f o r ( int i = l e n −1; i > 0 ; i −−) t r e e [ i ] = t r a n s ( t r e e [ 2 ∗ i ] , t r e e [ 2 ∗ i
+1]) ;
}

void update ( int p , T v ) {


p += l e n ; // t o g e t i t t o t h e c o r r e c t s p o t
tree [p] = v ;
while ( p != 1 ) {
p /= 2 ; // i n t d i v i s i o n makes (2 k+1)/2 ˜ k
t r e e [ p ] = t r a n s ( t r e e [ 2 ∗ p ] , t r e e [ 2 ∗ p +1]) ;
}
}

T query ( int l , int r ) { // [ l , r ]


// g e t them t o where we want
l += l e n ;
r += l e n ;
T r e s u l t = 0 ; // d e f a u l t v a l u e , change i f r e q u i r e d
while ( l < r ) {
i f ( l % 2 == 1 ) { // r i g h t c h i l d o f p a r e n t
// s h o u l d not i n c l u d e p a r e n t node
result = trans ( result , tree [ l ] ) ;

16
l ++;
}
i f ( r % 2 == 0 ) { // l e f t c h i l d o f p a r e n t
// s h o u l d not i n c l u d e p a r e n t node
result = trans ( result , tree [ r ] ) ;
r −−;
}
l /= 2 ;
r /= 2 ;
}
i f ( l == r ) r e s u l t = t r a n s ( r e s u l t , t r e e [ l ] ) ;
return r e s u l t ;
}
};

16 segtree-lazy.cpp
#include <b i t s / s t d c ++.h>
using namespace s t d ;

struct node {
node ∗ l , ∗ r ;
int val , s , m, e , l a z y a d d ;
node ( int s , int e ) : s ( s ) , e ( e ) , m( ( s+ e ) / 2 ) , v a l ( 0 ) , l a z y a d d ( 0 ) , l
(NULL) , r (NULL) {
i f ( s != e ) l = new node ( s , m) , r = new node (m+1, e ) ;
}
int v a l u e ( ) { // r e t u r n s t h e v a l u e o f t h e c u r r e n t node a f t e r l a z y
propagating
i f ( s == e ) return v a l + l a z y a d d ;
v a l += l a z y a d d ;
l −>l a z y a d d += lazyadd , r−>l a z y a d d += l a z y a d d ;
lazyadd = 0 ;
return v a l ;
}
void add ( int x , int y , int v ) {
i f ( s == x && e == y ) l a z y a d d += v ;
else {
i f ( x > m) r−>add ( x , y , v ) ;
e l s e i f ( y <= m) l −>add ( x , y , v ) ;
e l s e l −>add ( x , m, v ) , r−>add (m+1, y , v ) ;
v a l = min ( l −>v a l u e ( ) , r−>v a l u e ( ) ) ; // Change h e r e t o max
}
}
int query ( int x , int y ) {
value () ;
i f ( s == x && e == y ) return v a l u e ( ) ;
i f ( x > m) return r−>query ( x , y ) ;
i f ( y <= m) return l −>query ( x , y ) ;
return min ( l −>query ( x , m) , r−>query (m+1, y ) ) ; // Change h e r e t o max
}
};

int main ( ) {
int N, a [ 1 0 0 ] ;

/∗ I n c l u s i v e ∗/

17
node r o o t ( 0 , N−1) ;
/∗ I n i t i a l i z e i t t o an a r r a y v a l u e ∗/
f o r ( int i = 0 ; i < N; ++i ) r o o t . add ( i , i , a [ i ] ) ; // Add i s i n c l u s i v e
and i s O( l o g N)
r o o t . query ( 5 , 1 0 0 0 ) ; // Query i s O( l o g N) and i n c l u s i v e
}

17 segtree-lazy-progression.cpp
#include <b i t s / s t d c ++.h>
#pragma GCC o p t i m i z e ( ” O f a s t ” )
#pragma GCC t a r g e t ( ”avx , avx2 , fma” )
using namespace s t d ;
#define int long long
#define n l ’ \n ’
#define i o i o s b a s e : : s y n c w i t h s t d i o ( f a l s e ) ; c i n . t i e ( 0 ) ; c o u t . t i e ( 0 )
mt19937 rng ( ( unsigned ) chrono : : s t e a d y c l o c k : : now ( ) . t i m e s i n c e e p o c h ( ) . count
() ) ;
const int mod = 1 0 0 0 0 0 0 0 0 7 , mod2 = 9 9 8 2 4 4 3 5 3 ;

// change t h i s
const int N = 3 0 0 0 0 5 ;

int n , q , a r r [N ] ;

struct t d a t a {
int pf , s f , pfk , s f k , sub , l e n g t h ;
};

struct node {
int s , e , m, l a z y a d d = 0 , l a z y s e t = 0 , sum = 0 ;
tdata val ;
bool s t = f a l s e ;
node ∗ l , ∗ r ;

tdata fuck ( tdata a , tdata b) {


tdata res ;
res . length = a . length + b . length ;

// p r e f i x
r e s . p f = a . pf , r e s . p f k = a . p f k ;
i f ( r e s . p f == a . l e n g t h && a . p f k == b . p f k ) r e s . p f += b . p f ;

// s u f f i x
res . s f = b . sf , res . sfk = b . sfk ;
i f ( r e s . s f == b . l e n g t h && a . s f k == b . s f k ) r e s . s f += a . s f ;

// sub
r e s . sub = max( { min ( a . s f , a . l e n g t h −1) , min ( b . pf , b . l e n g t h −1) , a . sub ,
b . sub } ) ;
i f ( a . s f k == b . p f k ) r e s . sub = max( r e s . sub , min ( a . s f , a . l e n g t h −1) +
min ( b . pf , b . l e n g t h −1) ) ;
r e s . sub = min ( r e s . sub , r e s . l e n g t h − 2 ) ; // cannot be p r e f i x or
suffix

return r e s ;
}

18
void merge ( ) {
i f ( s == e ) return ;
propag ( ) ;
l −>propag ( ) ; r−>propag ( ) ;
sum = l −>sum + r−>sum ;

v a l = f u c k ( l −>val , r−>v a l ) ;
}

node ( int s , int e ) : s ( s ) , e ( e ) , m( ( s+ e ) / 2 ) {


i f ( s == e ) {
v a l . p f k = v a l . s f k = sum = ( a r r [ s ] − a r r [ s −1]) ;
val . pf = val . s f = val . length = 1;
v a l . sub = 0 ;
} else {
l = new node ( s , m) ;
r = new node (m+1, e ) ;
merge ( ) ;
}
}

void s e l f s e t ( int v ) {
st = 1;
l a z y s e t = val . pfk = val . s f k = v ;
lazyadd = 0 ;
sum = ( e−s +1) ∗ v ;
v a l . p f = v a l . s f = ( e−s +1) ;
v a l . sub = max( v a l . l e n g t h − 2 , 0 l l ) ;
}

void s e l f a d d ( int v ) {
if ( st ) {
s e l f s e t (v + lazyset ) ;
return ;
}
l a z y a d d += v ;
sum += ( e−s +1) ∗ v ;
// pf , s f e t c doesn ’ t change , o n l y t h e k v a l u e c h a n g e s
v a l . p f k += v , v a l . s f k += v ;
}

void propag ( ) {
i f ( s == e ) return ;
if ( st ) {
l −> s e l f s e t ( l a z y s e t ) ;
r−> s e l f s e t ( l a z y s e t ) ;
lazyset = st = 0;
}
i f ( lazyadd ) {
l −>s e l f a d d ( l a z y a d d ) ;
r−>s e l f a d d ( l a z y a d d ) ;
lazyadd = 0 ;
}
}

void add ( int x , int y , int v ) {


i f ( s == x && e == y ) s e l f a d d ( v ) ;

19
else {
propag ( ) ;
i f ( x > m) r−>add ( x , y , v ) ;
e l s e i f ( y <= m) l −>add ( x , y , v ) ;
e l s e l −>add ( x , m, v ) , r−>add (m+1, y , v ) ;
merge ( ) ;
}
}

void s e t ( int x , int y , int v ) {


i f ( s == x && e == y ) s e l f s e t ( v ) ;
else {
propag ( ) ;
i f ( x > m) r−>s e t ( x , y , v ) ;
e l s e i f ( y <= m) l −>s e t ( x , y , v ) ;
e l s e l −>s e t ( x , m, v ) , r−>s e t (m+1, y , v ) ;
merge ( ) ;
}
}

t d a t a query ( int x , int y ) {


propag ( ) ;
i f ( s == x && e == y ) return v a l ;
i f ( x > m) return r−>query ( x , y ) ;
i f ( y <= m) return l −>query ( x , y ) ;

return f u c k ( l −>query ( x , m) , r−>query (m+1, y ) ) ;


}

int rsum ( int x , int y ) {


propag ( ) ;
i f ( s == x && e == y ) return sum ;
i f ( x > m) return r−>rsum ( x , y ) ;
i f ( y <= m) return l −>rsum ( x , y ) ;
return l −>rsum ( x , m) + r−>rsum (m+1, y ) ;
}
} ∗ root ;

signed main ( ) {
io ;
c i n >> n >> q ;
f o r ( int i =1; i<=n ; i ++) c i n >> a r r [ i ] ;
r o o t = new node ( 1 , n ) ;

while ( q−−) {
int wh ;
c i n >> wh ;
i f (wh == 1 ) {
// sum
int l , r , s , c ;
c i n >> l >> r >> s >> c ;

r o o t −>add ( l , l , s ) ;
i f ( l < r ) r o o t −>add ( l +1, r , c ) ;
i f ( r < n ) r o o t −>add ( r +1, r +1, −( s + ( r−l ) ∗ c ) ) ;
} e l s e i f (wh == 2 ) {
// s e t
int l , r , s , c ;

20
c i n >> l >> r >> s >> c ;

int x = 0 , y ;
i f ( l > 1 ) x = r o o t −>rsum ( 1 , l −1) ;
i f ( r < n ) y = r o o t −>rsum ( 1 , r +1) ;

r o o t −>s e t ( l , l , s−x ) ;
i f ( l < r ) r o o t −>s e t ( l +1, r , c ) ;
i f ( r < n) {
int yy = r o o t −>rsum ( 1 , r +1) ;
r o o t −>add ( r +1, r +1, y − yy ) ;
}
} else {
// q u e r y
int l , r ;
c i n >> l >> r ;

t d a t a ans = r o o t −>query ( l , r ) ;
int r e s = max( { ans . pf , ans . s f +1, ans . sub +1}) ;
// c o u t << ans . p f << ’ ’ << ans . s f << ’ ’ << ans . sub << n l ;
r e s = min ( r e s , ans . l e n g t h ) ;
c o u t << r e s << n l ;
}
}
}

18 segtree-lazy-sum.cpp
struct SegmentTree {
int n ;
v e c t o r <int> a , t , l a z y ;

void i n i t ( int x ) {
n = x;
t . a s s i g n (4 ∗ n , 0) ;
lazy . a s s i g n (4 ∗ n , 0) ;
}

void i n i t ( int x , v e c t o r <int> y ) {


n = x;
a = y;
t . r e s i z e (4 ∗ n) ;
lazy . a s s i g n (4 ∗ n , 0) ;
build (1 , 0 , n − 1) ;
}

int merge ( int x , int y ) { return x + y ; }

int upd ( int x , int y ) { return x + y ; }

void b u i l d ( int i , int l , int r ) {


i f ( l == r ) {
t[ i ] = a[ l ];
return ;
}
int mid = ( l + r ) / 2 ;
b u i l d ( l c ( i ) , l , mid ) ;

21
b u i l d ( r c ( i ) , mid + 1 , r ) ;
t [ i ] = merge ( t [ l c ( i ) ] , t [ r c ( i ) ] ) ;
}

void push ( int i , int l , int r ) {


t [ i ] = upd ( t [ i ] , ( l a z y [ i ] ∗ ( r − l + 1 ) ) ) ;
i f ( l != r ) {
l a z y [ l c ( i ) ] = upd ( l a z y [ l c ( i ) ] , l a z y [ i ] ) ;
l a z y [ r c ( i ) ] = upd ( l a z y [ r c ( i ) ] , l a z y [ i ] ) ;
}
lazy [ i ] = 0;
}

void modify ( int i , int l , int r , int ql , int qr , int v a l ) {


i f ( l > qr | | r < q l ) return ;
i f ( l a z y [ i ] != 0 ) push ( i , l , r ) ;
i f ( l >= q l && r <= qr ) {
l a z y [ i ] = upd ( l a z y [ i ] , v a l ) ;
push ( i , l , r ) ;
return ;
}
int mid = ( l + r ) / 2 ;
modify ( l c ( i ) , l , mid , ql , qr , v a l ) ;
modify ( r c ( i ) , mid + 1 , r , ql , qr , v a l ) ;
t [ i ] = merge ( t [ l c ( i ) ] , t [ r c ( i ) ] ) ;
}

int query ( int i , int l , int r , int ql , int qr ) {


i f ( l > qr | | r < q l ) return 0 ;
i f ( l a z y [ i ] != 0 ) push ( i , l , r ) ;
i f ( l >= q l && r <= qr ) return t [ i ] ;
int mid = ( l + r ) / 2 ;
int r e s L = query ( l c ( i ) , l , mid , ql , qr ) ;
int resR = query ( r c ( i ) , mid + 1 , r , ql , qr ) ;
return merge ( resL , resR ) ;
}

void modify ( int l , int r , int v a l ) { modify ( 1 , 0 , n − 1 , l , r , v a l ) ; }

void modify ( int pos , int v a l ) { modify ( 1 , 0 , n − 1 , pos , pos , v a l ) ; }

int query ( int l , int r ) { return query ( 1 , 0 , n − 1 , l , r ) ; }

int query ( int pos ) { return query ( 1 , 0 , n − 1 , pos , pos ) ; }


};

19 sieve.cpp
b i t s e t <N+1> i s P r i m e ;
v e c t o r <int> p r i m e L i s t ;
/∗ I n i t i a l i z i n g e v e r y number ab o ve 1 t o be prime ∗/
isPrime . r e s e t () ;
isPrime . f l i p () ;
isPrime [ 0 ] = isPrime [ 1 ] = 0;

f o r ( int i =2; i<=N; i ++) {


i f ( ! i s P r i m e [ i ] ) continue ;

22
p r i m e L i s t . push back ( i ) ;
f o r ( int j = i ; j <= N/ i ; ++j ) i s P r i m e [ i ∗ j ] = 0 ;
}

20 smjleo-template.cpp
#include <b i t s / s t d c ++.h>
using namespace s t d ;
#define int long long
#define n l ’ \n ’
#define i o i o s b a s e : : s y n c w i t h s t d i o ( f a l s e ) ; c i n . t i e ( 0 ) ; c o u t . t i e ( 0 )
const int mod = 1 0 0 0 0 0 0 0 0 7 ;
const int mod2 = 9 9 8 2 4 4 3 5 3 ;

// change t h i s
const int N = 5 0 0 0 0 5 ;

signed main ( ) {
io ;

21 suffix-array.cpp
#include <b i t s / s t d c ++.h>
using namespace s t d ;
using l l = long long ;

v e c t o r <int> s o r t c y c l i c s h i f t s ( s t r i n g const& s ) {
int n = s . s i z e ( ) ;
const int a l p h a b e t = 2 5 6 ;

v e c t o r <int> p ( n ) , c ( n ) , c n t (max( a l p h a b e t , n ) , 0 ) ;

// b a s e c a s e ( s o r t t h e f i r s t c h a r s )

f o r ( int i = 0 ; i < n ; i ++)


cnt [ s [ i ]]++;

f o r ( int i = 1 ; i < a l p h a b e t ; i ++)


c n t [ i ] += c n t [ i − 1 ] ;

f o r ( int i = 0 ; i < n ; i ++)


p[−−c n t [ s [ i ] ] ] = i ;

c [p [ 0 ] ] = 0;

int c l a s s e s = 1 ;

f o r ( int i = 1 ; i < n ; i ++) {


i f ( s [ p [ i ] ] != s [ p [ i − 1 ] ] )
c l a s s e s ++;
c [p [ i ] ] = classes − 1;
}

23
v e c t o r <int> pn ( n ) , cn ( n ) ;

// 2ˆ h −> 2ˆ( h+1)

f o r ( int h = 0 ; ( 1 << h ) < n ; ++h ) {

// s o r t t h e second h a l v e s

f o r ( int i = 0 ; i < n ; i ++) {


pn [ i ] = p [ i ] − ( 1 << h ) ;
i f ( pn [ i ] < 0 )
pn [ i ] += n ;
}

f i l l ( cnt . begin ( ) , cnt . begin ( ) + c l a s s e s , 0) ;

// s o r t t h e f i r s t h a l v e s

f o r ( int i = 0 ; i < n ; i ++)


c n t [ c [ pn [ i ] ] ] + + ;

f o r ( int i = 1 ; i < c l a s s e s ; i ++)


c n t [ i ] += c n t [ i − 1 ] ;

f o r ( int i = n−1; i >= 0 ; i −−)


p[−−c n t [ c [ pn [ i ] ] ] ] = pn [ i ] ;

cn [ p [ 0 ] ] = 0 ;
classes = 1;

f o r ( int i = 1 ; i < n ; i ++) {


p a i r <int , int> c u r = { c [ p [ i ] ] , c [ ( p [ i ] + ( 1 << h ) ) % n ] } ;
p a i r <int , int> prev = { c [ p [ i − 1 ] ] , c [ ( p [ i −1] + ( 1 << h ) ) % n ] } ;
i f ( c u r != prev )
++c l a s s e s ;
cn [ p [ i ] ] = c l a s s e s − 1 ;
}

c . swap ( cn ) ;
}

return p ;
}

v e c t o r <int> s u f f i x a r r a y c o n s t r u c t i o n ( s t r i n g s ) {
s += ” $ ” ;
v e c t o r <int> s o r t e d s h i f t s = s o r t c y c l i c s h i f t s ( s ) ;
s o r t e d s h i f t s . erase ( s o r t e d s h i f t s . begin () ) ;
return s o r t e d s h i f t s ;
}

v e c t o r <int> l c p c o n s t r u c t i o n ( s t r i n g const& s , v e c t o r <int> const& p ) {


int n = s . s i z e ( ) ;
v e c t o r <int> rank ( n , 0 ) ;

f o r ( int i = 0 ; i < n ; i ++)


rank [ p [ i ] ] = i ;

24
int k = 0 ;
v e c t o r <int> l c p ( n−1, 0 ) ;

f o r ( int i = 0 ; i < n ; i ++) {


i f ( rank [ i ] == n − 1 ) {
k = 0;
continue ;
}

int j = p [ rank [ i ] + 1 ] ;

while ( i + k < n && j + k < n && s [ i+k ] == s [ j+k ] )


k++;

l c p [ rank [ i ] ] = k ;

if (k)
k−−;
}

return l c p ;
}

v e c t o r <int> p r e f i x f u n c t i o n ( s t r i n g s ) {
int n = ( int ) s . l e n g t h ( ) ;
v e c t o r <int> p i ( n ) ;

f o r ( int i = 1 ; i < n ; i ++) {


int j = p i [ i − 1 ] ;

while ( j > 0 && s [ i ] != s [ j ] )


j = pi [ j −1];

i f ( s [ i ] == s [ j ] )
j ++;

pi [ i ] = j ;
}

return p i ;
}

int main ( ) {
ios base : : sync with stdio ( false ) ; cin . t i e ( nullptr ) ;

s t r i n g s ; c i n >> s ;

auto p = s u f f i x a r r a y c o n s t r u c t i o n ( s ) ;

f o r ( int x : p ) c o u t << x << e n d l ;


}

22 trie-xor.cpp
const int b i t s = 2 9 ;

struct XORTrie {

25
struct Node {
array <int , 2> c h i l d ;
int c n t ;

Node ( ) {
cnt = 0 ;
c h i l d [ 0 ] = −1;
c h i l d [ 1 ] = −1;
}
};

v e c t o r <Node> t ;

XORTrie ( ) {
t . emplace back ( ) ;
t . emplace back ( ) ;
};

void c r e a t e c h i l d r e n ( int i ) {
i f ( t [ i ] . c h i l d [ 0 ] > −1) return ;

f o r ( int i d x = 0 ; i d x < 2 ; i d x++) {


t [ i ] . c h i l d [ idx ] = sz ( t ) ;
t . emplace back ( ) ;
}
}

void add ( int x ) {


int i d x = 1 ;

f o r ( int b i t = b i t s ; b i t >= 0 ; b i t −−) {


c r e a t e c h i l d r e n ( idx ) ;

int v i s i t = ( x & ( 1 << b i t ) ) > 0 ;

idx = t [ idx ] . c h i l d [ v i s i t ] ;
t [ i d x ] . c n t++;
}
}

void remove ( int x ) {


int i d x = 1 ;

f o r ( int b i t = b i t s ; b i t >= 0 ; b i t −−) {


c r e a t e c h i l d r e n ( idx ) ;

int v i s i t = ( x & ( 1 << b i t ) ) > 0 ;

i f ( t [ t [ idx ] . c h i l d [ v i s i t ] ] . cnt > 0)


idx = t [ idx ] . c h i l d [ v i s i t ] ;
e l s e break ;

t [ i d x ] . cnt −−;
}
}

int query ( int x ) {

26
int i d x = 1 ;

int r e s = 0 ;

f o r ( int b i t = b i t s ; b i t >= 0 ; b i t −−) {


int v i s i t = ( ( x & ( 1 << b i t ) ) > 0 ) ˆ 1 ;

c r e a t e c h i l d r e n ( idx ) ;

i f ( t [ t [ idx ] . c h i l d [ v i s i t ] ] . cnt > 0) {


r e s |= ( 1 << b i t ) ;
idx = t [ idx ] . c h i l d [ v i s i t ] ;
} else idx = t [ idx ] . c h i l d [ v i s i t ˆ 1 ] ;
}

return r e s ;
}
};

23 ufds.cpp
int num groups , p [N ] ;
int par ( int x ) { return ( p [ x ] == x ) ? x : p [ x ] = par ( p [ x ] ) ; }
bool isSameGroup ( int a , int b ) { return par ( a ) == par ( b ) ; }
void merge ( int a , int b ) {
num groups −= ( ! isSameGroup ( a , b ) ;
p [ par ( a ) ] = par ( b ) ;
}

/∗ I n i t i a l i z e ∗/
f o r ( int i = 0 ; i < N; ++i ) p [ i ] = i ;
num groups = N;

24 ufds-rank.cpp
int num groups , p [N] , g r p s i z e [N ] ;
int par ( int x ) { return ( p [ x ] == x ) ? x : p [ x ] = par ( p [ x ] ) ; }
bool isSameGroup ( int a , int b ) { return par ( a ) == par ( b ) ; }
void merge ( int a , int b ) {
a = par ( a ) , b = par ( b ) ;
num groups −= ( ! isSameGroup ( a , b ) ) ;
if ( grpsize [ a ] < grpsize [b ]) {
p[a] = b;
g r p s i z e [ b ] += g r p s i z e [ a ] ;
} else {
p[b] = a;
g r p s i z e [ a ] += g r p s i z e [ b ] ;
}
}

/∗ I n i t i a l i z e ∗/
f o r ( int i = 0 ; i < N; ++i ) p [ i ] = i , g r p s i z e [ i ] = 1 ;
num groups = N;

25 wavelet.cpp

27
#include <b i t s / s t d c ++.h>
using namespace s t d ;
#define gc g e t c h a r u n l o c k e d
#define f o ( i , n ) f o r ( i =0; i <n ; i ++)
#define Fo ( i , k , n ) f o r ( i=k ; k<n? i <n : i >n ; k<n? i +=1: i −=1)
#define l l long long
#define s i ( x ) s c a n f ( ”%d” ,&x )
#define s l ( x ) s c a n f ( ”%l l d ” ,&x )
#define s s ( s ) s c a n f ( ”%s ” , s )
#define p i ( x ) p r i n t f ( ”%d\n” , x )
#define p l ( x ) p r i n t f ( ”%l l d \n” , x )
#define ps ( s ) p r i n t f ( ”%s \n” , s )
#define deb ( x ) c o u t << #x << ”=” << x << e n d l
#define deb2 ( x , y ) c o u t << #x << ”=” << x << ” , ” << #y << ”=” << y << e n d l
#define pb push back
#define mp m a k e p a i r
#define F f i r s t
#define S s e c o n d
#define a l l ( x ) x . b e g i n ( ) , x . end ( )
#define c l r ( x ) memset ( x , 0 , s i z e o f ( x ) )
#define s o r t a l l ( x ) s o r t ( a l l ( x ) )
#define t r ( i t , a ) f o r ( auto i t = a . b e g i n ( ) ; i t != a . end ( ) ; i t ++)
#define PI 3 . 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6
typedef p a i r <int , int> p i i ;
typedef p a i r <l l , l l > pl ;
typedef v e c t o r <int> vi ;
typedef v e c t o r <l l > vl ;
typedef v e c t o r <p i i > vpii ;
typedef v e c t o r <pl> vpl ;
typedef v e c t o r <vi > vvi ;
typedef v e c t o r <vl > vvl ;
int mpow( int base , int exp ) ;
void i p g r a p h ( int m) ;
void d f s ( int u , int par ) ;
const int mod = 1 0 0 0 0 0 0 0 0 7 ;
const int N = 3 e5 , M = N;
//=======================
const int MAX = 1 e6 ;
v i g [N ] ;
int a [N ] ;

// //////////////////////////////////////////////////////////////

struct w a v e l e t t r e e {
#define v i v e c t o r <int>
#define pb push back
int l o , h i ;
wavelet tree ∗l , ∗r ;
vi b ;

// nos a r e i n range [ x , y ]
// a r r a y i n d i c e s a r e [ from , t o )
w a v e l e t t r e e ( int ∗ from , int ∗ to , int x , int y ) {
lo = x , hi = y ;
i f ( l o == h i or from >= t o ) return ;
int mid = ( l o+h i ) / 2 ;
auto f = [ mid ] ( int x ) {
return x <= mid ;

28
};
b . r e s e r v e ( to−from +1) ;
b . pb ( 0 ) ;
f o r ( auto i t = from ; i t != t o ; i t ++)
b . pb ( b . back ( ) + f ( ∗ i t ) ) ;
// s e e how lambda f u n c t i o n i s used h e r e
auto p i v o t = s t a b l e p a r t i t i o n ( from , to , f ) ;
l = new w a v e l e t t r e e ( from , p i v o t , l o , mid ) ;
r = new w a v e l e t t r e e ( p i v o t , to , mid+1, h i ) ;
}

// k t h s m a l l e s t e l e m e n t i n [ l , r ]
int kth ( int l , int r , int k ) {
i f ( l > r ) return 0 ;
i f ( l o == h i ) return l o ;
int i n L e f t = b [ r ] − b [ l − 1 ] ;
int l b = b [ l − 1 ] ; //amt o f nos i n f i r s t ( l −1) nos t h a t go i n l e f t
int rb = b [ r ] ; //amt o f nos i n f i r s t ( r ) nos t h a t go i n l e f t
i f ( k <= i n L e f t ) return this−>l −>kth ( l b +1, rb , k ) ;
return this−>r−>kth ( l −lb , r−rb , k−i n L e f t ) ;
}

// c ou n t o f nos i n [ l , r ] Less than or e q u a l t o k


int LTE( int l , int r , int k ) {
i f ( l > r or k < l o ) return 0 ;
i f ( h i <= k ) return r − l + 1 ;
int l b = b [ l −1] , rb = b [ r ] ;
return this−>l −>LTE( l b +1, rb , k ) + this−>r−>LTE( l −lb , r−rb , k ) ;
}

// c ou n t o f nos i n [ l , r ] e q u a l t o k
int count ( int l , int r , int k ) {
i f ( l > r or k < l o or k > h i ) return 0 ;
i f ( l o == h i ) return r − l + 1 ;
int l b = b [ l −1] , rb = b [ r ] , mid = ( l o+h i ) / 2 ;
i f ( k <= mid ) return this−>l −>count ( l b +1, rb , k ) ;
return this−>r−>count ( l −lb , r−rb , k ) ;
}
˜ wavelet tree () {
delete l ;
delete r ;
}
};

// ////////////////////////////////////////////////////////////////////

int main ( )
{
ios base : : sync with stdio ( false ) ;
c i n . t i e (NULL) ;
s r a n d ( time (NULL) ) ;
int i , n , k , j , q , l , r ;
c i n >> n ;
f o ( i , n ) c i n >> a [ i + 1 ] ;
w a v e l e t t r e e T( a+1, a+n+1, 1 , MAX) ;
c i n >> q ;
while ( q−−){
int x ;

29
c i n >> x ;
c i n >> l >> r >> k ;
i f ( x == 0 ) {
// k t h s m a l l e s t
c o u t << ”Kth s m a l l e s t : ” ;
c o u t << T . kth ( l , r , k ) << e n d l ;
}
i f ( x == 1 ) {
// l e s s than or e q u a l t o K
c o u t << ”LTE : ” ;
c o u t << T . LTE( l , r , k ) << e n d l ;
}
i f ( x == 2 ) {
// c ou n t o c c u r e n c e o f K i n [ l , r ]
c o u t << ” Occurence o f K: ” ;
c o u t << T . count ( l , r , k ) << e n d l ;
}
}
return 0 ;
}

30

You might also like