Professional Documents
Culture Documents
University of So Paulo
Template
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
2
2
3
3
4
4
4
4
4
5
5
5
5
6
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Combinatorics
Catalan Numbers . . . . . . . . . . .
Stirling Numbers of the First Kind .
Stirling Numbers of the Second Kind
Bell Numbers . . . . . . . . . . . . .
Narayana Numbers . . . . . . . . . .
The Twelvefold Way . . . . . . . . .
Partition (number theory) . . . . . .
Derangement (Desarranjo) . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6
6
6
6
7
7
7
7
7
Geometry 2D
Point Structure . . . . . . .
Auxiliary Functions . . . . .
Convex Hull . . . . . . . . .
Convex Polygon Intersection
Polygon-Line Intersection . .
Polygon Triangulation . . .
Closest Pair . . . . . . . . .
Crosses Half-Plane . . . . .
N segments Intersection . .
Circle Structure . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8
8
8
9
9
9
10
10
11
11
12
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Circle Intersection . . . . .
Circle Union . . . . . . . .
Minimum Spanning Circle
Circle-Polygon Intersection
.
.
.
.
12
12
13
13
Geometry 2D - Integer
Geometry Integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
13
Geometry 3D
Geometry 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
14
Graph
ErdsGallai theorem . . . . . . . . . . . . . . . . . . .
Stable Marriage . . . . . . . . . . . . . . . . . . . . . .
Dinic maxflow . . . . . . . . . . . . . . . . . . . . . . .
Min-cost maxflow . . . . . . . . . . . . . . . . . . . . .
Finding one solution for 2SAT . . . . . . . . . . . . . .
Stoer-Wagner algorithm for global mincut . . . . . . . .
Maximum matching in generic graph . . . . . . . . . .
Tarjans algorithm for Strongly Connected Components
Articulation point and Bridges . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
Strings
Aho-Corasick . . . . . . . . . .
Manachers algorithm for finding
Sux array . . . . . . . . . . .
Knuth-Morris-Pratt algorithm .
Hash . . . . . . . . . . . . . . .
Z-algorithm . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
15
15
15
16
17
18
18
18
19
20
. . . . . . . . . . . . . . . . .
longest palindromic substring
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
20
20
20
21
22
22
22
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
23
23
23
23
25
10 Data structures
Static Range Minimum Query . . .
2D Longest Increasing Subsequence
Treap . . . . . . . . . . . . . . . .
KD-Tree . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
University of So Paulo
Template
m. update ( trimmed )
hash = m. h e x d i g e s t ( ) [ : 4 ]
p r i n t "%s %s "%(hash , s a f e ) ,
iniciodeprova.txt
###### Emacs c o n f i g ######
( s e t q d e f a u l t i n d e n t t a b s mode n i l )
( setq c basic o f f s e t 4)
( g l o b a l linum mode 1 )
( e l e c t r i c i n d e n t mode 1 )
( g l o b a l u n s e t key "\C z " )
( g l o b a l u n s e t key "\C x\C z " )
( g l o b a l h l l i n e mode 1 )
( s e t f a c e background d e f a u l t "#202020")
( s e t f a c e f o r e g r o u n d d e f a u l t " White " )
( s e t f a c e background h l l i n e "#003399")
###### v i m r c ######
f i l e t y p e p l u g i n on
f i l e t y p e i n d e n t on
s e t number
s y n t a x on
s e t s h i f t w i d t h =4
s e t t a b s t o p =4
colorscheme
evening
2b74
916e
916e
a947
f69c
dd8c
40f4
a04e
2546
7c08
7c08
dd14
45e9
a13c
2b93
#include <bits/stdc++.h>
using namespace std;
#define
#define
#define
#define
#define
#define
#define
debug(x...) fprintf(stderr,x)
pb push_back
f(i,x,y) for(int i=x; i<y; i++)
quad(x) ((x)*(x))
clr(x,y) memset(x,y,sizeof x)
fst first
snd second
Suppose m0 , m1 , ..., mk 1 are positive integers that are pairwise coprime. Then, for any given sequence of integers
a1 , a2 , ..., ak 1 , there exists an integer X solving the following system of simultaneous congruences.
X a0
(mod m0 )
X a1
(mod m1 )
.
.
.
X ak
(mod mk
1)
University of So Paulo
Furthermore, all solutions X of this system are congruent modulo the product, M = m0 m1 ...mk
solution for this system is:
Pk 1 M
M
X =
1, m
bi 1 (mod mi ).
i=0 m bi ai , where bi is a integer, such that: 8i, 0 i k
i
1.
A possible
9b9c
1c31
1c31
1c31
839d
28c3
d300
82f4
bec2
18ca
12b8
12b8
12b8
ce3b
9e85
9e85
8818
ad2e
d092
e610
aa7c
9043
a3a9
5d5c
062f
bba8
01a9
ea7e
028a
1c22
6cab
fc88
9d61
e9cb
6e13
1479
569b
7ee2
74f4
344f
429d
c1fc
85bd
03b9
abcb
8fad
78e3 }
d/= 2; s++;
}
for (int k = 0; k < 64; k++) {
llu a = (llrand() % (n - 3)) + 2;
llu x = exp_mod(a, d, n);
if (x != 1 && x != n-1) {
for (int r = 1; r < s; r++) {
x = mul_mod(x, x, n);
if (x == 1)
return 0;
if (x == n-1)
break;
}
if (x != n-1)
return 0;
}
}
return 1;
llu rho(llu n) {
llu d, c = rand() % n, x = rand() % n, xx = x;
if (n % 2 == 0)
return 2;
do {
x = (mul_mod(x, x, n) + c) % n;
xx = (mul_mod(xx, xx, n) + c) % n;
xx = (mul_mod(xx, xx, n) + c) % n;
d = gcd(val_abs(x - xx), n);
} while (d == 1);
return d;
}
map <llu,int> F;
void factor(llu n) {
if (n == 1)
return;
if (is_probably_prime(n)) {
F[n]++;
return;
}
llu d = rho(n);
factor(d);
factor(n/d);
}
University of So Paulo
fk (x) =
x,
k=0
f fk
1 (x)
k>0
P (x) =
n
X
yi Pi (x),
i=1
where
Pi (x) =
n
Y
x
x
k=1 i
xk
xk
k6=j
Written explicitly,
P (x) =
(x
(x1
x2 )(x
x2 )(x1
x3 )...(x xn )
(x
y1 +
x3 )...(x1 xn )
(x2
x1 )(x
x1 )(x2
x3 )...(x xn )
y2 + ...
x3 )...(x2 xn )
(x
(xn
x1 )(x
x1 )(xn
x2 )...(x xn 1 )
yn .
x2 )...(xn xn 1 )
Luccas Theorem
For non-negative integers m and n and a prime p, the following congruence relation holds:
m
n
k
Y
mi
i=0
ni
Farey Sequence
(mod p),
Farey Sequence of order n is the sequence of completely reduced fractions between 0 and 1 which, when in lowest
terms, have denominators less than or equal to n, arranged in order of increasing size.
F1 = {0/1, 1/1}, F2 = {0/1, 1/2, 1/1}, F3 = {0/1, 1/3, 1/2, 2/3, 1/1}, ...
where
m = mk pk + mk 1 pk 1 + ... + m1 p + m0
and
n = nk pk + nk 1 pk 1 + ... + n1 p + n0
are the base p expansions of m and n respectively.
f (x) dx
a
6
"
f (a) + 4f (
a+b
) + f (b)
2
Suppose that the interval [a, b] is split up in n subintervals, with n an even number. Then, the composite
Simpsons rule is given by:
Z
b
a
f (x) dx
n 1
n
"
2
2
X
X
h
f (x0 ) + 2
f (x2j ) + 4
f (x2j
3
j=1
j=1
b
a
f (x) dx
|Fn | = |Fn
The asymptotic behaviour of |Fn | is : |Fn |
1)
+ f (xn )
"
h
f (x0 ) + 4f (x1 ) + 2f (x2 ) + 4f (x3 ) + 2f (x4 ) + ... + 4f (xn
3
1)
+ f (xn )
d41d
d41d
d41d
d41d
e3cd
2e8e
8781
6ab6
dea7
7c2d
7c2d
12b6
12b6
d0f3
c77b
6cc1
6cc1
d737
877c
877c
0509
3n2
2
1|
+ '(n)
University of So Paulo
c557
278a
278a
8330
f7c2 }
p|n
'(mn) = '(m)'(n).
1
p
'(p.n) =
(p
1)'(n),
pn
p|n
p'(n),
d
, where d = gcd(m, n). N ote the special cases.
'(d)
k
'(p ) = p
1
p
'(d) = n;
d|n
'(n)
(mod n)
n
X
k=1
P (n) =
X
d|n
d'(n/d) (n 2 N)
n
X
( 1)
gcd(k, n) =
aP (m) =
Gaussian Elimination
Can be easily adapted to integers mod P, fractions and long doubles.
b94a
b94a
6d0c
c19b
c19b
33d8
bdd8
09a1
if n is odd;
n,
2a
09a1
09a1
09a1
09a1
09a1
c993
b764
96b9
a12c
3bf0
43da
e8ad
45fb
c4e9
7188
ddf6
b465
0aab
f452
291f
d1de
d898
2e81
558c
e221
868e
1320
d2ac
f3af
68fa
ee55
aae1
95f1
f9ce
c884
b5d4
e4b2
19cf
a
a+2 P (n),
if n is even.
6dba
b9dc
b9dc
b9dc
6ca7
7ca9
7e69
e1c7
University of So Paulo
4d07
7df5
3e55
ba11
a97d
5e4f
1a64
48a4
c108
7a46
15e7
2b20
1085
8e81
66f2
a81b
c40c
b83f
a0e0
5d65 }
vector<Complex> v2(n);
for(int i=0; i<n; i++) {
int mask = 0;
for(int j=0; j<logn; j++) if(i&(1<<j)) mask |= (1<<(logn - 1 - j));
v2[mask] = v[i];
}
for(int s=0, m=2; s<logn; s++, m<<=1) {
Complex wm(cos(2.L * type * PI / m), sin(2.L * type * PI / m));
for(int k=0; k<n; k+=m) {
Complex w = 1;
for(int j=0; 2*j<m; j++) {
Complex t = w * v2[k + j + (m>>1)], u = v2[k + j];
v2[k + j] = u + t; v2[k + j + (m>>1)] = u - t;
w *= wm;
}
}
}
if(type == -1) for(Complex &c: v2) c /= n;
return v2;
It holds that:
h ni
k
For integers n
..
.
...
< g 0 , gn 1 >
< g 1 , gn 1 >
.
.
.
< g n 1 , gn 1 >
32
76
76
76
76
54
a0
a1
.
.
.
an
7
6
7
6
7=6
7
6
5
4
< f, g0 >
< f, g1 >
.
.
.
< f, gn 1 >
0,
It holds that:
1,
n=0
0,
n 6= 0
h ni
7
7
7
7
5
where x
and y are the mean value of x and y, respectively.
= (n
h0i
1)!;
h n i
nn
=
;
n 3
2
4
In the linear discrete case when g(x) = ax + b, a and b can also be found using the following equations:
Pn
y)
i=1 xi (yi
a = Pn
,
b = y a
x
x
)
i=1 xi (xi
h ni
...
...
Hn =
n
X
1
,
j
j=1
h ni
2
(k)
Hn
1,
k=0
0,
k 6= 0
h ni
h n i
n
=
;
n 1
2
= (n
1)!Hn
h ni
1;
k=0
1)
hn
h n i
1
= (3n
n 2
4
3
n h i
X
n
n
X
1
;
jk
j=1
= (n
1i
1)
n h i
X
n j
= n!;
j=k
1i
;
1
n
3
2
1)! Hn
1
(n
2
hn
;
(2)
Hn
hn + 1 i
k+1
n no
is the number of ways to partition an n-set into exactly k non-empty disjoint subsets up to a permutation of
k
the sets among themselves. It holds that:
n no
Combinatorics
1,
0,
n no
k
Catalan Numbers
n no
Cn is:
The number of balanced expressions built from n pairs of parentheses.
The number of paths in an n n grid that stays on or below the diagonal.
The number of words of size 2n over the alphabet = {a, b} having an equal number of a symbols and b
symbols containing no prefix with more a symbols than b symbols.
(starting with C0 ): 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440,
9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650,
1289904147324, 4861946401452...
2n
1 2n
(2n)!
=
=
n 1
n+1 n
n!(n + 1)!
is:
Let f, g0 , g1 , ..., gn 1 be given functions. The coecients of the function g(x) = a0 g0 (x)+a1 g1 (x)+...+an 1 gn 1 (x)
that best fits f (x) so that the inner product < f g, f g > is minimum is given by the system of equations below.
< g0 , g1 >
< g1 , g1 >
.
.
.
< gn 1 , g1 >
< g0 , g0 >
< g1 , g0 >
.
.
.
< gn 1 , g0 >
2n
Cn =
6
6
6
6
4
C k Cn
k=0
h ni
n
X
C0 = 1, Cn+1 =
=2
1;
mod 2 =
n=0
n 6= 0
nn
k
8
<0,
:1,
n no
1
n no
n
n n 1o
1o
+k
1
k
(n
k)&
otherwise
n n o
n
=
;
n 1
2
n no
k
1
2
=1
6= 0
k
1 X
k
( 1)
k! j=0
k
j
j ;
University of So Paulo
Bell Numbers
Bn is the number of equivalence relations on an n-set or, alternatively, the number of partitions of an n-set. It holds
that:
A partition of a positive integer n, is a way of writing n as a sum of positive integers. Two sums that dier only in
the order of their summands are considered to be the same partition. The number of partitions of n is given by the
partition function p(n). Ex: p(4) = 5 => {1+1+1+1} , {1+1+2} , {1+3} , {2+2} , {4}.
Bn =
n n o
X
n
k=0
Bn+1 =
n
X
n
k=0
Bn+p Bn + Bn+1
Bk ;
Bn =
1
1 X kn
;
e k=0 k!
(mod p)
(starting with B0 ): 1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597, 27644437, 190899322,
1382958545, 10480142147, 82864869804, 682076806159, 5832742205057, 51724158235372, 474869816156751,
4506715738447323, 44152005855084346, 445958869294805289, 4638590332229999353, ...
Narayana Numbers
N (n, k), n = 1, 2, 3..., 1 k n, is the number of expressions containing n pairs of parentheses which are correctly
matched and which contain k distinct nestings. For instance, N(4, 2) = 6 as with four pairs of parentheses six
sequences can be created which each contain two times the sub-pattern (): ()((())) (())(()) (()(())) ((()()))
((())()) ((()))().
The number of partitions of n in which the greatest part is m is equal to the number of partitions of n into m
parts.
The number of partitions of n in which all parts are 1 or 2 (or, equivalently, the number of partitions of n into
1 or 2 parts) is b n
2 + 1c.
(starting with p(0) = 1): 1, 1, 2, 3, 5, 7, 11, 15, 22, 30, 42, 56, 77, 101, 135, 176, 231, 297, 385, 490, 627...
P
p
k(3k 1)
k 1
Summation to calculate p(n) for the first n elements in O(n n) time. p(n) =
p(n
),
k ( 1)
2
where the summation is over all nonzero integers k (positive and negative) and p(m) is taken to be 0 if m < 0.
p(5k + 4) 0 (mod 5)
p(7k + 5) 0 (mod 7)
p(11k + 6) 0 (mod 11)
p(113 .13.k + 237) 0 (mod 13)
N (n, k) = 0, if k > n
Derangement (Desarranjo)
N (n, 1) = N (n, n) = 1
A derangement is a permutation of the elements of a set such that none of the elements appear in their original
position.
Suppose that there are n persons numbered 1, 2, . . . , n. Let there be n hats also numbered 1, 2, . . . , n. We have
to find the number of ways in which no one gets the hat having same number as his/her number. Let us assume
that first person takes the hat i. There are n 1 ways for the first person to choose the number i. Now there are 2
options:
N (n, k) =
N (n, k) =
(n
1 n n
n k k 1
n(n 1)
N (n
k)(n k + 1)
1, k)
m6n
k
n
k=0
m
n
m 1
+ n 1
6
m
m
n 1
n
X
(*)
p(m, k)
(**)p(m, n)
m6n
k=0
(**) is a definition and both (*) and (**) are very hard to compute. So do not try to.
Person i takes the hat of 1. Now the problem reduces to n 2 persons and n 2 hats.
Person i does not take the hat 1. This case is equivalent to solving the problem with n 1 persons n 1 hats
(each of the remaining n 1 people has precisely 1 forbidden choice from among the remaining n 1 hats).
From this, the following relation is derived:
dn = (n
1) (dn
+ dn
2)
d1 = 0
d2 = 1
Starting with n = 0, the numbers of derangements of n are: 1, 0, 1, 2, 9, 44, 265, 1854, 14833, 133496, 1334961,
14684570, 176214841, 2290792932.
University of So Paulo
Geometry 2D
Point Structure
271c
c9c4
4c40
4c40
13ed
5753
0188
a930
4fac
9684
e00a
08fb
ed7d
a117
370c
92cf
cc80
1b1c
0db4
425f
fc93
ed60
30cd
bf2c
b780
9948
522c
ddfe
Auxiliary Functions
160a
ab7c
ab7c
27db
69a1
34b1
34b1
34b1
06d3
6a85
126a
126a
126a
126a
6c5c
bf72
bc40
615a
615a
615a
a582
51cd
9480
9480
9480
cab9
0ee2
e529
9307
5a00
a282
e435
c388
b193
b193
b193
f311
3285
b348
3b09
d2b9
f5b7
ed51
ed51
ed51
ed51
ed51
cf13
5047
7f2c
6ea3
0935
8850
294c
8a8d
8a8d
8a8d
550d
d6fd
49b7
ae66
ae66
ae66
ae66
ae66
78f3
fe30
f7e8
23db
ccd3
549a
549a
}
//Decide se q esta sobre o segmento fechado pr.
bool between(point p, point q, point r) {
return ccw(p, q, r) == 0 && cmp((p - q) * (r - q)) <= 0;
}
//Decide se os segmentos fechados pq e rs tem pontos em comum
bool seg_intersect(point p, point q, point r, point s) {
point A = q - p, B = s - r, C = r - p, D = s - q;
int a = cmp(A % C) + 2 * cmp(A % D);
int b = cmp(B % C) + 2 * cmp(B % D);
if (a == 3 || a == -3 || b == 3 || b == -3) return false;
if (a || b || p == r || p == s || q == r || q == s) return true;
int t = (p < r) + (p < s) + (q < r) + (q < s);
return t != 0 && t != 4;
}
// Calcula a distancia do ponto r ao segmento pq.
double seg_distance(point p, point q, point r) {
point A = r - q, B = r - p, C = q - p;
double a = A * A, b = B * B, c = C * C;
if (cmp(b, a + c) >= 0) return sqrt(a);
else if (cmp(a, b + c) >= 0) return sqrt(b);
else return fabs(A % B) / sqrt(c);
}
// Classifica o ponto p em relacao ao poligono T.
// Retorna 0, -1 ou 1 dependendo se p esta no exterior, na fronteira
// ou no interior de T, respectivamente.
int in_poly(point p, polygon& T) {
double a = 0; int N = T.size();
for (int i = 0; i < N; i++) {
if (between(T[i], p, T[(i+1) % N])) return -1;
a += angle(T[i], p, T[(i+1) % N]);
}
return cmp(a) != 0;
}
//Encontra o ponto de intersecao das retas pq e
point line_intersect(point p, point q, point r,
point a = q - p, b = s - r, c = point(p % q,
return point(point(a.x, b.x) % c, point(a.y,
}
rs.
point s) {
r % s);
b.y) % c) / (a % b);
University of So Paulo
549a
585a
f167
3b2d
7752
7752
7752
3df1
e7c6
9823
6227
308e
5bd2
48e2
bbb9
efc0
Convex Hull
d41d
d41d
d41d
f7bf
1cb2
69c0
f7e9
ea84
119c
119c
119c
119c
5b79
548d
76fb
bfee
4a7a
6a93
6a93
b5fc
b5fc
a64e
426e
bd98
df01
519d
e39f
// Comparacao radial.
// Obs: suponha tds pontos no vetor p[] = p[]-pivot, (pivot = min_elemento(p))
// tds ptos do novo p[] estarao no 1 e 4 quadrante ordenado no sentido anti-hor
bool radial_lt(point p, point q) {
point P = p - point::pivot, Q = q - point::pivot;
double R = P % Q;
if (cmp(R)) return R > 0;
return cmp(P * P, Q * Q) < 0;
}
// Determina o fecho convexo de um conjunto de pontos no plano.
// Destroi a lista de pontos T.
polygon convex_hull(vector<point>& T) {
int j = 0, k, n = T.size(); polygon U(n);
point::pivot = *min_element(all(T));
sort(all(T), radial_lt);
for (k = n-2; k >= 0 && ccw(T[0], T[n-1], T[k]) == 0; k--);
reverse((k+1) + all(T));
for (int i = 0; i < n; i++) {
// troque o >= por > para manter pontos colineares
while (j > 1 && ccw(U[j-1], U[j-2], T[i]) >= 0) j--;
U[j++] = T[i];
}
U.erase(j + all(U));
return U;
Polygon-Line Intersection
}
d41d
d41d
d41d
abcb
c8be
5ec6
//retorna tds trechos da reta que passa por s(s.a != s.b) coberta
//por p(simple polygon)
//tempo:O(n log n), memoria: O(n), onde n = p.size() TODO testar
vector <segment> cobertura(segment s, polygon p) {
if (cmp(poly_area(p)) < 0) reverse(all(p)); //p deve esta no sentido anti-hr
int n = (int)p.size();
University of So Paulo
5ec6
ed2a
a951
592f
a782
73c9
3fc2
3fc2
3630
3630
14b9
aab9
02c0
82d2
6957
e155
84d6
c42e
d4d8
50e6
50e6
fa88
6c84 }
polygon q;
p.pb(p[0]), p.pb(p[1]), p.pb(p[2]);
for (int i = 1; i <= n; i++) {
point u = p[i], v = p[i+1];
int d0 = ccw(s.a,s.b,p[i-1]), d1 = ccw(s.a,s.b,p[i]);
int d2 = ccw(s.a,s.b,p[i+1]), d3 = ccw(s.a,s.b,p[i+2]);
if (d1 == d2) continue;
if (d1 * d2 == -1)
q.pb(line_intersect(s.a, s.b, u, v));
else if (d1 == 0 && (d0*d2 == -1 || ccw(p[i-1], p[i], p[i+1]) > 0))
q.pb(line_intersect(s.a, s.b, u, v));
else if (d2 == 0 && ccw(p[i], p[i+1], p[i+2]) > 0 && d1*d3 >= 0)
q.pb(line_intersect(s.a, s.b, u, v));
}
sort(all(q));
vector <segment> seg;
for (int i = 0; i < q.size(); i += 2) seg.pb( segment(q[i], q[i+1]));
return seg;
Polygon Triangulation
395e
80e5
80e5
80e5
eef9
9db8
c0f0
a8dc
a8dc
5a7a
038b
2b13
1567
c9eb
b43f
4cf0
cac8
b1e3
b1e3
b1e3
e82d
aea2
2911
2911
9b58
e616
fd13
fd13
aa38
0401
08d2
229e
229e
229e
229e
05eb
05eb
0bed
41b5
e844
a6df
85d8
c9f0
37ca
2202
2202
b944
7fe3 }
prox[i] = ((i+1<n)?(i+1):(i+1-n));
orelha[i] = eh_orelha(p, i);
}
while (n > 3) {
while (!orelha[id]) id = prox[id];
//triangulo p[id], p[prev[id]], p[prox[id]]
//diagonal inserida => prev[id] <-> prox[id]
printf("%2d %2d %2d\n", id, prox[id], prev[id]);
int ant = prev[id], next = prox[id];
prox[ant] = next;
prev[next] = ant;
orelha[ant] = eh_orelha(p, ant);
orelha[next] = eh_orelha(p, next);
n--;
id = prox[id];
}
//triangulo p[id], p[prox[id]], p[prox[prox[id]]]
printf("%2d %2d %2d\n", id, prox[id], prox[prox[id]]);
Closest Pair
904d
35c2
1db4
6b34
6b34
c8e3
4705
6f5b
6f5b
6f5b
31d9
37f0
dfc0
dfc0
6568
f57e
a0d9
264f
8b4b
4faa
323f
1eb9
6fb0
c40a
c40a
f209
5430
University of So Paulo
6e13
for (int j = max(0, i-8); j < i; j++)
bad4
resp = min(resp, (Y[i]-Y[j]).mod2());
3bfb
}
0ccc
return resp;
9b71 }
9b71
9b71
ce21 double closest_pair(vector <point> &p) {
cb73
for (int i = p.size()-1; i >= 0; i--) X[i] = Y[i] = p[i];
88d6
sort(X, X+p.size());
fffe
sort(Y, Y+p.size(), cmpy);
3ad4
return sqrt(divide_conquer(p.size(), 0, &X[0], &Y[0]));
9554 }
Crosses Half-Plane
d41d
d41d
d41d
d41d
3755
c316
3b60
3b60
3b60
4981
f194
9a0e
88e0
7689
9df1
1d83
c519
1645
9943
N segments Intersection
67e3
0bfd
dfe5
fb83
72c2
7e34
08e1
5f79
8abb
8abb
fd2a
a86d
typedef ll ptype;
struct segment {
point a, b;
segment(point a=point(0,0), point b=point(0,0)): a(a), b(b) {}
double interpolate(ptype x) {
if (a.x == b.x) return min(a.y, b.y);
return a.y + (double)(b.y - a.y) / (b.x - a.x) * (x - a.x);
}
};
struct event {
ptype x;
f8b1
56d0
d428
0551
5ae4
c7e3
c7e3
60c0
dc88
c5a6
bc5e
1a89
276a
e3c1
49a9
ab9c
ab9c
083a
8737
e3b4
1985
1985
4fcf
fee1
12fd
12fd
6be6
7136
f399
9c01
b204
f7e9
4839
f1b8
bec0
bec0
3058
66a2
d61e
323b
323b
38f1
cf62
08b9
68c6
ae7e
a7da
15b5
c496
9bf4
2465
af6f
db87
3472
07d6
University of So Paulo
c2b5
85a3
5edd }
ff4a
80cd
fe16
2b8c
081c
d825
88a4
Circle Structure
88a4
4d74
aa81 struct circle {
7e41
5235
point c; double r;
8b21
0ba6
circle(point c = point(0,0), double r=0.0):c(c), r(r) {}
8b21
639a
bool inside(point &e) { return cmp((e-c).mod(), r) <= 0; }
ae3c
9757 };
ae3c
a1cf
8514
9d66
1354
Circle Intersection
dbe0
607c
d41d //assume que ha pelo menos 1 ponto de interseccao
b7d1
d41d //cuidado com circulos iguais, sem intersecao (um dentro do outro)
7470
9b67 pair<point, point> interseccao(circle a, circle b) {
0581
4979
if (cmp(a.r, b.r) < 0) swap(a, b);
029f
99d7
double R = a.r, r = b.r, d = (b.c-a.c).mod();
029f
ee39
double x1 = (R*R - r*r + d*d) / (2*d);
35e2
9881
double h = 0.0;
59b4
f8cf
if (cmp(R*R - x1*x1) > 0) h = sqrt(R*R - x1*x1);
59b4
2cb8
point v = ((b.c-a.c)/d) * R;
3298
48ac
return mp(a.c + v.rotate(h/R, x1/R), a.c + v.rotate(-h/R, x1/R));
4514
ee26 }
4514
65d8
f064
64e4
Circle Union
7453
d4d3
f244 void increment(double ini, double fim, double &Area, double &Perim, circle &q) { a2ca
a489
5456
double teta = (cmp(fim,ini)>=0) ? (2*Pi-fim+ini) : (ini-fim);
7592
7959
Perim += teta * q.r;
13e7
6dde
Area += 0.5*teta*quad(q.r) - 0.5*sin(teta)*quad(q.r);
74ac
f25f
point a = (point(cos(fim), sin(fim)) * q.r) + q.c;
bf78
557d
point b = (point(cos(ini), sin(ini)) * q.r) + q.c;
240b
7f51
Area += 0.5*(a % b);
2bf4
e7cf }
6d26
e7cf //Calcula a area e o perimetro em O(n^2*logn)
accc
e7cf //Consome memoria O(n)
4654
b0a6 double area_uniao_circle(vector <circle> &T) {
79eb
f354
vector <circle> p;
8c91
ee7b
vector < pair<double, double> > seg;
dfa2
554f
point e, a, b;
b486
2ff7
double Area = 0, Perim = 0, teta, ini, fim;
6444
2ff7
2ff7
//remove circles repitidos, com area nula, ou circle dentro de outro circle 8849
08f5 }
c3ee
f(i, 0, T.size()) {
2fcf
bool check = cmp(T[i].r) > 0;
}
return mp(-1,-1);
}
for (int i = 0; i < p.size(); i++) {
seg.clear();
for (int j = 0; j < p.size(); j++) if (i != j) {
//p[i] e p[j] nao tem 2 pontos em comum
if ((p[i].c-p[j].c).mod() > p[i].r + p[j].r -eps) continue;
pair <point, point> inter = interseccao2(p[i], p[j]);
teta = angle(inter.first, p[i].c, inter.second);
if (teta > eps) {
e = (inter.first - p[i].c).rotate(teta/2) + p[i].c;
if (p[j].inside(e) == false) swap( inter.first, inter.second);
}
else {
e = (inter.first - p[i].c).rotate((2*Pi+teta)/2) + p[i].c;
if (p[j].inside(e) == false) swap( inter.first, inter.second);
}
ini = (inter.first - p[i].c).polar();
fim = (inter.second - p[i].c).polar();
a = (point(cos(ini), sin(ini)) * p[i].r) + p[i].c;
b = (point(cos(fim), sin(fim)) * p[i].r) + p[i].c;
if (ini > fim) {
seg.pb( mp(ini, 2*Pi));
seg.pb( mp(0, fim));
}
else seg.pb( mp(ini, fim));
}
sort(all(seg));
if ((int) seg.size() == 0) {
Perim += 2*Pi*p[i].r;
Area += Pi*quad(p[i].r);
continue;
}
fim = seg[0].second;
for (int j = 1; j < seg.size(); j++) {
if (cmp(fim, seg[j].first) < 0) {
increment(seg[j].first, fim, Area, Perim, p[i]);
}
fim = max(fim, seg[j].second);
}
increment(seg[0].first, fim, Area, Perim, p[i]);
}
return Area;
University of So Paulo
6b33
bd68 }
return fabs(ans);
Circle-Polygon Intersection
d41d
6673
6421
91ca
a8b9
a8b9
3da3
eadd
ffb6
726d
6c18
6c18
5fcf
18c2
7c63
7c63
7c63
64ab
643c
2a56
65d0
ef35
Geometry 2D - Integer
Geometry Integer
bd39
5fd8
4e39
15ac
d57a
d57a
d57a
ee01
3992
e388
2acd
5180
4842
4842
4842
4842
4842
4842
4842
8390
2696
17f8
3065
6ba3
786a
198d
38bc
78eb
a580
a580
a580
a580
a580
a580
a580
a580
a580
a580
a580
ebb2
18f8
c585
c585
0d3d
0d3d
//TESTAR XXX
//////////////////////////////////////////////////////////////////////////////
// Returns a list of points on the convex hull in counter-clockwise order.
// Note: the last point in the returned list is the same as the first one.
// Se T.size()==1 => H.size()==1
//trocar ccw(H[k-1], T[i], H[k-2]) <= 0 por ccw(...) < 0,
//para incluir pts colineares
// Monotone hull O(nlogn)
polygon convex_hull(vector<point> T) {
int n = T.size(), k = 0;
polygon H(2*n);
sort(T.begin(), T.end());
// Build lower hull
University of So Paulo
8045
50b0
8c5e
608e
608e
0201
1007
b5d8
9df1
94cb
7a34
2e5b }
e08c
d6d7
4b8c
4b8c
4b8c
7880
44f8
b5fd
4442
6e35
479c
2e96
bc3c
79a8
3de6
de90
7 Geometry 3D
df01
7581
Geometry 3D
b6cc
3bfe
b44d
a616 #define vetor point
af47
a616
f643
a616 // FORMULAS.
6b62
a616 // vetores a,b; a*b = a.mod()*b.mod()*cos( angulo entre a e b) =>
6b62
a616 // a*b = |a|*|b|*cos(t)
6b62
a616 // vetores a,b; (a^b).mod() = a.mod()*b.mod()*sin( angulo entre a e b)
1780
a616
f9f6
45c8 inline int cmp(ld x, ld y = 0, ld tol = eps) {
1f9f
2939
return (x <= y + tol) ? (x + tol < y) ? -1 : 0 : 1;
2b63
426f }
2b63
858c struct point {
2b63
148a
ld x, y, z;
1ba8
a276
point(ld x = 0, ld y = 0, ld z = 0): x(x), y(y), z(z) {}
ef7a
78a6
point operator +(point q) { return point(x + q.x, y + q.y, z + q.z); }
dc8e
d092
point operator -(point q) { return point(x - q.x, y - q.y, z - q.z); }
f81e
55b5
point operator *(ld t) { return point(x * t, y * t, z * t); }
6d1e
0646
point operator /(ld t) { return point(x / t, y / t, z / t); }
0366
0286
point operator ^(point q) {
1ea3
b5e0
return point(y*q.z - z*q.y, z*q.x - x*q.z, x*q.y - y*q.x); }
1ea3
10a6
ld operator *(point q) { return x * q.x + y * q.y + z * q.z; }
1ea3
44b7
ld mod() { return sqrt(x * x + y * y + z * z); }
a2a0
8344
ld mod2() { return x * x + y * y + z * z; }
feaf
point projecao(vetor u) { return (*this) * ((*this)*u) / ((*this)*(*this)); } 56b2
8db1
feaf
8db1
5eb8
int cmp(point q) const {
059b
ff5c
if (int t = ::cmp(x, q.x)) return t;
e035
82ce
if (int t = ::cmp(y, q.y)) return t;
11d5
d86a
return ::cmp(z, q.z);
11d5
940d
}
11d5
9b26
bool operator ==(point q) const { return cmp(q) == 0; }
4985
b245
bool operator !=(point q) const { return cmp(q) != 0; }
ee85
ce46
bool operator < (point q) const { return cmp(q) < 0; }
2f7c
bb0f };
4a60
bb0f
8dea
bb0f // RETAS, SEMIRETAS, SEGMENTOS E TRIANGULOS
struct reta {
point a, b;// <--a---b--->
reta(point A=point(0,0,0), point B=point(0,0,0)): a(A), b(B) { }
//verifica se o ponto p esta na reta ab
bool belongs(point p) {
return cmp(((a-p)^(b-p)).mod()) == 0;
}
};
struct semireta {
point a, b; // |a---b--->
semireta(point A=point(0,0,0), point B=point(0,0,0)): a(A), b(B) { }
};
struct segmento {
point a, b; // |a---b|
segmento(point A=point(0,0,0), point B=point(0,0,0)): a(A), b(B) { }
bool between(point p) {
return cmp(((a-p)^(b-p)).mod()) == 0 && cmp((a-p) * (b-p)) <= 0;
}
};
struct triangulo {
point a, b, c;
triangulo(point A, point B, point C): a(A), b(B), c(C) { }
ld area() { return 0.5*((b-a)^(c-a)).mod(); }
//retorna o ponto que eh a projecao de p no plano abc
point projecao(point p) {
vetor w = (b-a)^(c-a);
return p - w.projecao(p-a);
}
//verifica se p esta dentro de abc
// se retornar true, entao a,b,c,p sao coplanares
bool inside(point p) {
return cmp(((p-a)^(b-a)).mod() +
((p-b)^(c-b)).mod() +
((p-c)^(a-c)).mod() ((b-a)^(c-a)).mod()) == 0;
}
};
//Produto misto
ld produto_misto(point p, point q, point r) {
return (p^q)*r;
}
//Volume do tetraedro pqrs
ld volume(point p, point q, point r, point s) {
return fabs(produto_misto(q-p, r-p, s-p)) / 6.0;
}
// DISTANCIA ENTRE OBJETOS GEOMETRICOS
ld distancia(point p, reta r) {
vetor v = r.b-r.a, w = p-r.a;
return (v^w).mod() / v.mod();
}
ld distancia(point p, semireta s) {
University of So Paulo
3c72
341c
b99b
1027
cdef
7700
cb69
8d5f
ad83
55c4
1268
a756
c71d
0e8c
c3f9
cf4b
4622
3f36
65cd
4b58
4a12
23fb
6ee7
b72c
cce1
bd44
9c8d
5d82
d414
4733
f55a
8eae
e75f
397b
0da3
4849
1f96
9028
cf88
6402
185c
b645
4231
ff9e
39c6
78e4
5fdb
320d
320d
320d
fd93
6645
c16b
39fe
39fe
39fe
c9a7
1653
7118
a779
05bf
26be
e1e1
d5fe
4a16
fc14
9023
9023
9023
9023
1da8
4015
9d39
814e
1e07
89c3
b08d
3002
9d7d
Graph
ErdsGallai theorem
A sequence of non-negative integers d1
di k(k
1) +
n
X
min(di , k)
i=k+1
holds for 1 k n.
Stable Marriage
a511
a511
5e20
68c0
6589
2baa
7fc7
7fc7
fc77
802c
07a0
W[maxn][maxn], M[maxn][maxn];
quem[maxn]; //quem[i] = homem q a mulher i casa
ja[maxn]; //ja[i] = mulher que o cara i casa
topo[maxn];
n;
University of So Paulo
13ac
b334
4aa7
4aa7
4aa7
b9be
bb77
1b4d
07f4
2b4e
6ad6
b929
45ef
0227
203f
feff
3321
3a7c
2021
78d3
e453
5e2b
5e2b
17bb
a3d0
cd6d
6172
feda
19d4
52db
a790
eb1d
2bab
e7ef
3296
153e
b9ad
d607
cda2
2213
0a5d
5c21
26cb
b19c
7b3f
5840
5840
dec7
f516
Dinic maxflow
d41d
d41d
d41d
469e
469e
1adb
1b9b
1b9b
3922
b25e
7173
47ea
d4ff
d4ff
bcdd
5509
dbcd
dbcd
dbcd
6358
0a1b
a469
2e59
6571
66ca
66ca
31a3
c9a4
fac6
ecd3
cc20
5524
b2fc
3a8a
1e8a
c984
2aa0
8b60
3c55
3322
9840
eb49
febd
c28a
0f3a
0f3a
dfab
bd70
4b3f
31a5
6de4
1b53
b77c
// define as needed
University of So Paulo
b722
c013
d24b
8152
ba4c
0545
d9ee
bc36
c298
c298
1110
f3b1
351d
49e8
3d97
c875
da59
aeed
aeed
aeed
46d7
0db6
e3fc
38fc
if(got) {
edge[ind].cap -= got;
edge[ind^1].cap += got;
return got;
}
}
}
return 0;
}
FTYPE dinic(int _s,int _t) {
FTYPE ret = 0, got;
while(dinic_bfs(_s,_t)) {
memset(ptr,0,sizeof(ptr));
while((got = dinic_dfs(_s,_t,FINF))) ret += got;
}
return ret;
}
// Clears dinic structure
inline void dinic_clear() {
for(int a=0;a<MAXV;++a) adj[a].clear();
edge.clear();
}
Min-cost maxflow
d41d
d41d
d97f
e6a7
4551
4551
1c31
54b0
b6ba
b6ba
b844
b844
ba37
09c7
45f8
4417
2771
7093
7093
96f2
5234
c32a
c32a
c32a
4864
c4cf
aa3f
787c
f5c6
d0d9
d0d9
a5df
0045
bac0
ded6
ded6
f9d1
f123
7647
6410
1719
d96c
ea3c
4429
6092
cec9
2f1a
411c
0098
3046
3046
6793
405b
e94d
1f2b
8d6c
ec7b
6d38
8599
30a8
5370
ce7a
9ada
8afc
3b54
9de4
610c
1a34
31f8
71fb
e26d
3669
07af
5228
f290
2565
0577
6aaf
43c0
c20c
adj[u].push_back(edge.size());
edge.push_back(Edge(v,c,cst));
adj[v].push_back(edge.size());
edge.push_back(Edge(u,0,-cst));
}
FTYPE flow[MAXV];
CTYPE dist[MAXV], pot[MAXV];
int prv[MAXV], e_ind[MAXV];
bool foi[MAXV];
void bellman_ford(int _s) {
for(int a=0;a<V;++a) dist[a] = CINF;
dist[_s] = 0;
for(int st=0;st<V;++st) {
for(int v=0;v<V;++v) {
for(size_t a=0;a<adj[v].size();++a) {
int ind = adj[v][a];
int nxt = edge[ind].to;
if(!edge[ind].cap) continue;
dist[nxt] = min(dist[nxt],dist[v] + edge[ind].cost);
}
}
}
}
pfc dijkstra(int _s,int _t) { // O(V^2)
for(int a=0;a<V;++a) {
dist[a] = CINF;
foi[a] = 0;
}
dist[_s] = 0;
flow[_s] = FINF;
while(1) {
int v;
CTYPE d = CINF;
for(int a=0;a<V;++a) {
if(foi[a] || dist[a] >= d) continue;
d = dist[a];
v = a;
}
if(d == CINF) break;
foi[v] = 1;
for(size_t a=0;a<adj[v].size();++a) {
int ind = adj[v][a];
int nxt = edge[ind].to;
if(!edge[ind].cap || dist[nxt] <= dist[v] +
edge[ind].cost + pot[v] - pot[nxt]) continue;
dist[nxt] = dist[v] + edge[ind].cost + pot[v] - pot[nxt];
prv[nxt] = v;
e_ind[nxt] = ind;
flow[nxt] = min(flow[v],edge[ind].cap);
}
}
if(dist[_t] == CINF) return pfc(FINF,CINF);
University of So Paulo
efac
de63
9208
e8c6
3e32
5464
f53a
1c33
3620
fc6b
fc6b
fc6b
c9d9
b783
24bc
4f45
8e0a
0045
0241
0241
0241
8377
e477
1245
8892
3a33
b8b0 int StoerWagner() {
b942
int ret = INF;
3405
for(int siz=n;siz>1;--siz) {
26ba
for(int a=0;a<n;++a) {
7a96
sum[a] = 0;
7113
foi[a] = out[a];
5bae
}
daae
int i=0;
d6f7
while(1) {
13a0
int v,d=-1;
9ed3
for(int a=0;a<n;++a) {
d5a2
if(!foi[a] && sum[a] > d) {
ea58
d = sum[a];
4484
v = a;
10ae
}
296a
}
be90
if(d==-1) break;
49f4
foi[v] = 1;
5dac
ord[i++] = v;
7cc7
for(int a=0;a<deg[v];++a) {
a55e
int nxt = adj[v][a];
563c
if(!foi[nxt]) sum[nxt] += cost[v][nxt];
eea1
}
89ee
}
8607
int s = ord[siz-2], t = ord[siz-1];
10c1
ret = min(ret, sum[t]);
4d8d
out[t] = 1;
679e
for(int a=0;a<deg[t];++a) {
6290
int nxt = adj[t][a];
06ef
if(s==nxt) continue;
f771
if(cost[s][nxt]==0) {
1773
adj[s][deg[s]++] = nxt;
94fc
adj[nxt][deg[nxt]++] = s;
5c51
}
4c12
cost[s][nxt] += cost[t][nxt];
51ce
cost[nxt][s] += cost[nxt][t];
6fcb
}
d8c9
}
30d8
return ret;
e9e7 }
//
//
//
Algoritmo de Stoer-Wagner
Encontra o corte minimo em um grafo
Complexidade: O(N^3)
d41d
d41d
d41d
50ac
50ac
5285
9124
int n;
// numero de vertices
vector<int> adj[MAXN]; // lista de adj
University of So Paulo
2a7d
fe16
cd46
cd46
3229
e3c9
0c59
eb63
a684
1ad4
8cdd
79f3
1750
0912
1b7d
a0f5
0a76
c88a
c88a
4072
a48d
f79f
3c8d
5ab4
efc3
0ac9
d657
d657
d969
c0ba
2939
7022
450a
b9c4
044c
6cd2
b731
7ab6
e2fd
8a3c
0cab
ab27
95e1
680e
7930
e755
7d5b
f4b3
9269
fa64
d079
0583
d224
5acb
f979
int match[MAXN];
// match[i] eh o par de i. -1 se nao tem par
int p[MAXN], base[MAXN] , q[MAXN];
bool used[MAXN], blossom[MAXN];
int lca ( int a, int b ) {
bool used [MAXN] = {0};
for ( ;; ) {
a = base [a];
used [a] = true;
if ( match[a] == -1 ) break;
a = p[match[a]];
}
for ( ;; ) {
b = base[b];
if ( used[b] ) return b;
b = p[match[b]];
}
}
void mark_path ( int v, int b, int children ) {
while ( base[v] != b ) {
blossom[base[v]] = blossom[base[match[v]]] = true;
p[v] = children;
children = match[v];
v = p[match[v]];
}
}
int find_path ( int root ) {
memset ( used, 0 , sizeof used );
memset ( p, - 1 , sizeof p );
for ( int i = 0 ; i < n ; ++i )
base[i] = i;
used[root] = true;
int qh = 0 , qt = 0;
q[qt++] = root;
while ( qh < qt ) {
int v = q[qh++];
for ( size_t i = 0; i < adj[v].size(); ++i ) {
int to = adj[v][i];
if ( base[v] == base[to] || match[v] == to ) continue;
if ( to == root || match[to] != -1 && p[match[to]] != -1 ) {
int curbase = lca ( v, to );
memset ( blossom, 0 , sizeof blossom );
mark_path ( v, curbase, to );
mark_path ( to, curbase, v );
for ( int i = 0 ; i < n ; ++i ) {
if ( blossom[base[i]] ) {
base[i] = curbase;
if ( !used[i] ) {
used[i] = true;
q[qt++] = i;
}
}
}
b476
398f
6af0
b064
1172
7e68
ec93
82f8
333d
1362
f167
120f
38fd }
38fd
b5b7 int
b5b7
326e
326e
c118
f9fa
7257
0c38
877f
9af3
6223
527f
95ab
6d85
8796
5da4
d98e
8ba9
039e
55b1
5729
ab71
b34d
be6f
2db7
2db7
110d }
}
else if ( p[to] == -1 ) {
p[to] = v;
if ( match[to] == -1 )
return to;
to = match[to];
used[to] = true;
q[qt++] = to;
}
}
}
return -1;
main() {
// ler grafo
memset ( match, -1 , sizeof match );
// otimizacao: comeca com um matching parcial guloso
for ( int i = 0 ; i < n ; ++i ) {
if ( match[i] == -1 ) {
for ( size_t j = 0 ; j < adj[i].size() ; ++j ) {
if ( match[ adj[i][j] ] == -1 ) {
match[ adj[i][j] ] = i;
match[i] = adj[i][j];
break;
}
}
}
}
for ( int i = 0 ; i < n ; ++ i ) {
if ( match[i] == - 1 ) {
int v = find_path(i);
while ( v != -1 ) {
int pv = p[v], ppv = match[pv];
match[v] = pv, match[pv] = v;
v = ppv;
}
}
}
// ...
University of So Paulo
b69c
5387
471e
3b9d
d9cf
329e
65c3
1da7
9394
0cdb
6ad9
5a5c
6e2f
ff4b
c01c
a0cd
43d7
01d6
b008
8e76
c759
dac1 }
9663
1c41
85ab }
// v eh um ponto de articulacao
}
Strings
Aho-Corasick
1ec0
0176
631f
ed2d
ed2d
b5eb
b5eb
da6a
afc3
f085
b391
d26c
8816
404a
ceb6
0749
0749
e6be
a46c
0498
d60a
601a
db6c
a687
7125
b451
6ce2
1aff
90ab
ed7d
eae4
b5dc
44a0
e3ee
1532
#define
#define
#define
#define
MAXS 1000
MAXT 100000
MAX 100000
cc 52
char s[200000];
int n;
// Encontrar palindromos - inicializa d1 e d2 com zeros, e eles guadram
// o numero de palindromos centrados na posicao i (d1[i] e d2[i])
University of So Paulo
b90a
0245
6103
adee
e50f
96d1
b185
7404
86ca
7b9c
e5c3
9a4e
9a4e
61d8
f943
5ec6
1a46
4712
b698
1f61
7e38
7a76
d167
// impar
int d1[200000], d2[200000];
void imp(){
int l=0, r=-1;
for (int i=0; i<n; ++i) {
int k = (i>r ? 0 : min (d1[l+r-i], r-i)) + 1;
while (i+k < n && i-k >= 0 && s[i+k] == s[i-k]) ++k;
d1[i] = --k;
if (i+k > r)
l = i-k, r = i+k;
}
}
// par
void par(){
int l=0, r=-1;
for (int i=0; i<n; ++i) {
int k = (i>r ? 0 : min (d2[l+r-i+1], r-i+1)) + 1;
while (i+k-1 < n && i-k >= 0 && s[i+k-1] == s[i-k]) ++k;
d2[i] = --k;
if (i+k-1 > r)
l = i-k, r = i+k-1;
}
}
Sux array
e9bf
e9bf
0bf5
b7a0
b7a0
b7a0
b7a0
b7a0
b7a0
c70a
c70a
759d
e78c
f2ec
fbe8
dcaa
b346
128a
fbac
53fc
bd68
eb4b
9d6a
94a0
978e
7bfc
4948
16f8
38ec
bc0a
4b4b
4b4b
53a1
53a1
b4b7
9ac6
e803
8552
0c03
c9e6
2227
1631
40ba
6b94
399c
c661
a7d9
4163
264b
dca2
cde0
9c7d
07c5
8107
dfb9
1c1e
3f74
6aa9
6aa9
6aa9
6aa9
c9c7
b858
04ef
e889
e84b
995d
3362
5cc9
493f
f31c
b6d1
f49d
00f3
1b8d
0486
}
void suff_arr() {
int i, j, bc[256];
t = 1;
for(i = 0; i < 256; i++) bc[i] = 0;
//alfabeto
University of So Paulo
Knuth-Morris-Pratt algorithm
33c2
5f1e
ab34
245b
93f5
8dad
2b5b
7fbd
7186
3e31
dc81
89d1
6c79
3ad8
48f3
d73c
63e2
11d9
0562
c0b7
51a9
f206
4675
15df
2e00
3f8e
3f8e
56a6
d8c1
0744
c9ce
54c5
4846
6d09
bb49
4c96
2a3b
25d0
eb70
f16c
1f75
938a
49a4
a285
abdb
class KMP {
private:
string pattern;
int len;
public:
vector<int> f;
KMP(string p) {
pattern = p;
len = p.size();
f.resize(len+2);
f[0] = f[1] = 0;
for(int a=2;a<=len;++a) {
int now = f[a-1];
while(1) {
if(p[now] == p[a-1]) {
f[a] = now+1;
break;
}
if(now==0) {
f[a] = 0;
break;
}
now = f[now];
}
}
}
//returns a vector of indices with the beginning of each match
vector<int> match(string text) {
vector<int> ret;
int size = text.size();
int i=0,j=0;
while(j<size) {
if(text[j] == pattern[i]) {
++i; ++j;
if(i==len) {
ret.push_back(j-len);
i = f[i];
}
}
else if(i>0) i = f[i];
else j++;
}
return ret;
}
};
Hash
dc9a typedef char HType;
dc9a
0c12
0c12
ec30
d084
0d28
0f7b
b917
afbc
ac5b
547d
3369
8aaa
f1f5
674f
6710
ba95
e26c
1895
b83d
c53d
bb50
56f7
56f7
2b89
2b89
5df8
bd84
c2d0
d0df
8ace
6231
ab47
ecc9
4d55
6b7f
26eb
26eb
aa1a
bda8
65e1
0e4b
Z-algorithm
d41d
d41d
d41d
dfb2
297a
d7d5
57ec
e35e
// Z-algorithm, O(N)
// Builds array z such that z[i] = size of longest prefix substring
// starting at index i
vector<int> Z(string s) {
vector<int> z(1,s.size());
int l=0,r=0;
for(int a=1;a<(int)s.size();++a) {
if(r < a) {
University of So Paulo
ae49
8690
ea6e
e7b0
9141
4f00
cae0
d3a9
552c
657f
0258
7bee
f580
f2fc
c455 }
10
l = r = a;
while(r<(int)s.size() && s[r] == s[r-l]) ++r;
z.push_back(r-l);
r--;
}
else if(z[a-l] < r-a+1) z.push_back(min<int>(z[a-l],s.size()-a));
else {
l = a;
while(r<(int)s.size() && s[r] == s[r-l]) ++r;
z.push_back(r-l);
r--;
}
}
return z;
Data structures
int rmq[LOG][MAXN];
int v[MAXN];
int n;
// Builds RMQ structure for array v of size n in O(n*log(n))
void build_rmq() {
for(int i = 0; i < n; i++)
rmq[0][i] = v[i];
for(int log = 1; log < LOG; ++log)
for(int i = 0; i < n; i++)
rmq[log][i] = min(rmq[log-1][i],
rmq[log-1][min(n-1, i + (1<<(log-1)))]);
}
// l e r inclusives
int get_rmq(int l,int r) {
int len = r - l + 1;
int bit = 31 - __builtin_clz(len);
return min(rmq[bit][l], rmq[bit][r - (1<<bit) + 1]);
}
struct ponto{
int x,y;
bool operator <(const ponto& p) const { return x<p.x; }
};
ponto v[MAXN];
set<ponto> m[MAXN];
set<ponto> :: iterator it;
bde8
bde8
5fe8
ffbb
9fd2
6696
de4f
1b6e
c573
0390
b739
55fc
a393
a393
cf14
2c2c
d3ba
a479
a0ee
584d
7dcf
d9e1
d9e1
5c14
6c55
7bdd
7c8a
985b
41ae
0941
4e53
e33a
7916
ff35
927a
f8a9
8fb5
int n, t;
void insere(int p, ponto c){
if(p>t)t++;
it = m[p].lower_bound(c);
vector< ponto > tira;
for(;it!=m[p].end();it++){
if(it->y >= c.y) tira.pb(*it);
else break;
}
for(int j=0;j<sz(tira);j++) m[p].erase(tira[j]);
m[p].insert(c);
}
bool cabe(int p, int i){
if(p==0) return false;
if(p==t+1) return true;
it = m[p].lower_bound(v[i]);
if(it == m[p].begin()) return true;
it--;
return v[i].y <= it->y;
}
int lis(){
t=0;
f (i, 0, n) m[i].clear();
for(int i=0;i<n;i++){
int l=0,r=t+1, j;
while(l!=r){
j = (l+r)/2;
if(!cabe(j,i)) l=j+1;
else r=j;
}
insere(l,v[i]);
}
return t;
}
Treap
d41d // Supports insertion, deletion, querying kth-element and finding element
d41d // Keeps duplicate elements as different nodes
d41d
10aa template <class T> class Treap {
d02a
struct Node {
a39f
T val;
2112
int h,cnt;
bfcc
Node *l, *r;
588c
Node(T val2) {
ed02
val = val2;
1501
h = rand();
e0eb
cnt = 1;
University of So Paulo
cd33
b66b
cb40
0efa
6510
2612
e761
d4ef
b26d
f737
74a9
205f
2a7b
1885
993f
731b
1f9e
b3c9
7762
b75b
aca0
cc9c
ed45
7741
f999
203f
6a29
19fb
930c
60c7
0531
da12
1663
dcd3
325a
757d
a155
721a
a9d0
43b5
6cd0
f742
4efc
79b4
1704
5c1f
5e00
ca41
02b9
0301
9863
7961
9103
a81a
a81a
l = r = NULL;
}
};
Node *root;
inline Node* newNode(T val) { return new Node(val); }
inline void refresh(Node *node) {
if(node == NULL) return;
node->cnt = (node->l == NULL ? 0 : node->l->cnt) +
(node->r == NULL ? 0 : node->r->cnt) + 1;
}
void _insert(Node *&node, T val) {
if(node == NULL) {
node = newNode(val);
return;
}
if(val <= node->val) {
_insert(node->l, val);
if(node->l->h > node->h) {
Node *aux = node->l;
node->l = aux->r;
aux->r = node;
node = aux;
refresh(node->r);
refresh(node);
}
else refresh(node);
}
else {
_insert(node->r, val);
if(node->r->h > node->h) {
Node *aux = node->r;
node->r = aux->l;
aux->l = node;
node = aux;
refresh(node->l);
refresh(node);
}
else refresh(node);
}
}
Node* merge(Node *L,Node *R) {
if(L == NULL) return R;
if(R == NULL) return L;
if(L->h < R->h) {
L->r = merge(L->r,R);
refresh(L);
return L;
}
else {
R->l = merge(L,R->l);
refresh(R);
return R;
}
}
// not used. splits node into two trees a(<=val) and b(>val)
314d
void split(T val, Node *node, Node *&a, Node *&b) {
05c5
if(node == NULL) {
5cdb
a = b = NULL;
069b
return;
f1a9
}
0f67
Node *aux;
496e
if(val > node->val) {
44c0
split(val,node->r,aux,b);
c4a9
node->r = aux;
2145
a = node;
d30c
refresh(a);
64c5
}
4bca
else {
6a72
split(val,node->l,a,aux);
372d
node->l = aux;
426d
b = node;
f8ae
refresh(b);
cfb4
}
79c4
}
79c4
// erases a single appearence of val
42f8
void _erase(Node *&node, T val) {
f6ee
if(node == NULL) return;
3a82
if(node->val > val) _erase(node->l, val);
70b2
else if(node->val < val) _erase(node->r, val);
bdea
else node = merge(node->l,node->r);
323c
refresh(node);
8fb2
}
8fb2
// 0-indexed (not safe if element doesnt exist)
9fa7
int _kth(Node *node,int k) {
3a77
int ql = (node->l == NULL ? 0 : node->l->cnt);
efe4
if(k < ql) return _kth(node->l,k);
7072
if(k == ql) return node->val;
209f
k -= ql + 1;
61e3
return _kth(node->r,k);
1509
}
1509
// returns position (0-indexed) of element val. -1 if it doesnt exist
560f
int _find(Node *node, T val) {
5713
if(node == NULL) return -1;
d526
if(node->val == val) return (node->l == NULL ? 0 : node->l->cnt);
d502
else if(node->val > val) return _find(node->l,val);
2893
else {
7cec
int pos = _find(node->r,val);
53a4
if(pos == -1) return -1;
76f9
return 1 + (node->l == NULL ? 0 : node->l->cnt) + pos;
509e
}
d04b
}
d07b
void _clear(Node *&node) {
3224
if(node == NULL) return;
7ad7
_clear(node->l); _clear(node->r);
6120
delete node;
c349
node = NULL;
46e2
}
bdb0 public:
06c9
Treap() { root = NULL; }
0b2f
void insert(T val) { _insert(root,val); }
University of So Paulo
547c
4978
7544
6986
ac7e
a350 };
KD-Tree
be52
e3bf
a0fa
d25b
b9f7
cc29
1152
1152
149d
5e32
8257
6a86
6a86
dcaf
e3e5
d2e9
7b48
2fe5
d31e
d31e
f38d
777c
ce32
0982
26c3
74d7
d403
1a75
c8c3
c8c3
41fd
9124
d0f8
598d
b820
799c
406c
d9c3
a157
375a
375a
1a75
7d28
struct point {
ll x, y, z;
point(ll x=0, ll y=0, ll z=0): x(x), y(y), z(z) {}
point operator-(point q) { return point(x-q.x, y-q.y, z-q.z); }
ll operator*(point q) { return x*q.x + y*q.y + z*q.z; }
};
typedef vector<point> polygon;
struct KDTreeNode {
point p;
int level;
KDTreeNode *below, *above;
KDTreeNode (const point& q, int levl) {
p = q;
level = levl;
below = above = 0;
}
~KDTreeNode() { delete below, above; }
int diff (const point& pt) {
switch (level) {
case 0: return pt.x - p.x;
case 1: return pt.y - p.y;
case 2: return pt.z - p.z;
}
return 0;
}
ll distSq (point& q) { return (p-q)*(p-q); }
int rangeCount (point& pt, ll K) {
int count = (distSq(pt) < K*K) ? 1 : 0;
int d = diff(pt);
if (-d <= K && above != 0)
count += above->rangeCount(pt, K);
if (d <= K && below != 0)
count += below->rangeCount(pt, K);
return count;
}
};
class KDTree {
public:
106f
130c
a4ad
f095
91b1
7cf8
14e0
5d49
3061
e8ab
2035
2035
2035
fee1
890b
f4d3
f807
e5bf
8eb5
8eb5
f1ed
544a
c821
b93b
a894
937f
23aa
f1db
f750
9ba3
ee91
e0eb
d4e8
247d
36e9
8ced
5747
dd9f
ca38
ca38
d70e
1a3c
20fc
2efb
e672
8293
0fbb
9912
7ce5
faf5
e75f
6ada
ae2c
77c1
c2ab
polygon P;
KDTreeNode *root;
int dimention;
KDTree() {}
KDTree(polygon &poly, int D) {
P = poly;
dimention = D;
root = 0;
build();
}
~KDTree() { delete root; }
//count the number of pairs that has a distance less than K
ll countPairs(ll K) {
ll count = 0;
f(i, 0, P.size())
count += root->rangeCount(P[i], K) - 1;
return count;
}
protected:
void build() {
random_shuffle(all(P));
f(i, 0, P.size()) {
root = insert(root, P[i], -1);
}
}
KDTreeNode *insert(KDTreeNode* t, const point& pt, int parentLevel) {
if (t == 0) {
t = new KDTreeNode (pt, (parentLevel+1) % dimention);
return t;
} else {
int d = t->diff(pt);
if (d <= 0) t->below = insert (t->below, pt, t->level);
else t->above = insert (t->above, pt, t->level);
}
return t;
}
};
int main() {
int n, k;
point e;
polygon p;
while (cin >> n >> k && n+k) {
p.clear();
f(i, 0, n) {
cin >> e.x >> e.y >> e.z;
p.pb(e);
}
KDTree tree(p, 3);
cout << tree.countPairs(k) / 2LL << endl;
}
return 0;
}