Professional Documents
Culture Documents
Template
/* Author : Turing Machine */
#include <iostream>
#include <cstdio>
#include <vector>
#include <cassert>
#include <sstream>
#include <map>
#include <set>
#include <climits>
#include <stack>
#include <queue>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdlib>
using namespace std;
#define
#define
#define
#define
#define
#define
#define
#define
.vimrc
=========================================
set shiftwidth=3
set makeprg=g++\ %\ -Wall
map <F3> :w <CR> :make<CR> <CR>
map <F2> :cn<CR>
imap <tab> <c-n>
set cindent
autocmd BufNewFile *.cpp r ~/start.cpp
set wrapscan
=========================================
typedef pair<int,int>
typedef vector<int>
typedef long long
PI;
VI;
LL;
Graph Theory
Topological Sort
//tOrd = topologicalOrder
//tSort = topologicalSort
#define MAXN 200000
int n,visited[MAXN];
vector<PI> graph[MAXN];
VI tOrd;
void dfs(int i){
if(visited[i]) return;
visited[i] = true;
EACH(it,graph[i]) dfs(it->first);
tOrd.PB(i);
}
void tSort(){
tOrd.clear();memset(visited,0,sizeof(visited));
REP(i,n) dfs(i);
}
Bellman-Ford
int n,dist[MAXN];
int bellmanFord(int source,int destination) {
fill(dist, dist + n, INF); dist[source] = 0;
REP (i,n+1) {
bool state = false;
REP (j,n) EACH (it,graph[j]) if (dist[it->first] > dist[j] + it->second) {
dist[it->first] = (dist[j] + it->second);
state = true;
}
3
}
}
if(state) return -INF; // Negative Weight Cycle.
return dist[destination];
}
Bi-Connected Components
VI graph[100003],G2[100003];/* G2[i] will store all the vertices in component i */
int visited[100003],from[100003],upTime[100003],discoveryTime[100003],label[100003], dfsTime,n;
void dfs(int v){
int parentEdges=0;visited[v] = 1;
upTime[v] = discoveryTime[v] = ++dfsTime;
EACH(it,graph[v]){
if(!visited[*it]){
from[*it] = v;dfs(*it);upTime[v] <?= upTime[*it];
}
else {
if(*it != from[v]){
upTime[v] <?= discoveryTime[*it];
}
else {
if(parentEdges) upTime[v] <?= discoveryTime[*it];
parentEdges++;
}
}
}
}
bool isBridge(int i,int j){
if(from[i] != j && from[j] != i) return false;
int low = ((from[i] == j)?i:j);
return (upTime[low] == discoveryTime[low]);
}
void FindBridges(int root){
from[root] = root;dfsTime = 0;
fill(visited,visited+n,0);dfs(root);
}
void ContractCercuits(int root){
fill(label,label+n,0);label[root] = 1;int color = 1;
queue<int> q;q.push(root);
while(!q.empty()){
int cur = q.front();q.pop();
EACH(it,graph[cur]) if(!label[*it]){
if(isBridge(cur,*it)){
label[*it] = ++color;
}
else {
label[*it] = label[cur];
}
q.push(*it);
}
}
REP(i,color) G2[i].clear();
4
REP(i,n) if(label[i]) G2[label[i]-1].PB(i);
}
Dijkstra Algorithm
int n,dist[MAXN];
int dijkstra(int source, int destination) {
fill(dist, dist + n, INF); dist[source] = 0;
set<PI> s; s.insert(PI(0, source));
while (!s.empty()) {
PI top = *s.begin(); s.erase(s.begin());
if (top.second == destination) {
return dist[destination];
}
EACH (it,graph[top.second]) {
if (dist[it->first] > dist[top.second] + it->second) {
if (dist[it->first] != INF) {
s.erase(s.find(PI(dist[it->first], it->first)));
}
dist[it->first] = dist[top.second] + it->second;
s.insert(PI(dist[it->first], it->first));
}
}
}
return INF;
}
5
int bfs() {
fill(ALL(Layers),-1);
Layers[sink] = 0;
queue<int> Q; Q.push(sink);
int top, from, to, cap, index;
while(!Q.empty()) {
top = Q.front(); Q.pop();
REP(i,graph[top].size()) {
from = graph[top][i].to; index = graph[top][i].back;
if(graph[from][index].cap && Layers[from] == -1) {
Layers[from] = Layers[top] + 1;
Q.push(from);
}
}
}
return (Layers[source] != -1);
}
int dfs(int node,int val) {
if(node == sink) {
return val;
}
int flow, to, cap;
for(int& start = now[node] ; start < graph[node].size(); ++start) {
to = graph[node][start].to;
cap = graph[node][start].cap;
if(cap > 0 && Layers[node] == Layers[to] + 1) {
flow = dfs(to,min(val,cap));
if(flow) {
graph[node][start].cap -= flow;
graph[to][graph[node][start].back].cap += flow; return flow;
}
}
}
return 0;
}
int flow() {
int ret = 0, flow = 0;
while(bfs()) {
fill(ALL(now),0);
while(flow = dfs(source,INF)) ret += flow;
}
return ret;
}
};
Bipartite Matching
#define Max 60000
VI graph[Max];
int visited[Max], match[Max], pos[Max], track;
int dfs(int i) {
6
int size, j;
if(visited[i] == track) return 0;
visited[i] = track;
size = graph[i].size();
REP(loop,size) {
if(++pos[i] == size) pos[i] = 0;
j = graph[i][pos[i]];
if(match[j] < 0 || dfs(match[j])) {
match[j] = i;
return 1;
}
}
return 0;
}
int matching() {
memset(visited,0,sizeof visited);
memset(pos,0,sizeof pos);
memset(match,-1,sizeof match);
int ret = 0;
REP(i,n) {
if(graph[i].size()) {
++track; ret += dfs(i);
}
}
return ret;
}
7
for (j = 0; j < ny && X[i] < 0; j++) {
if (Lx[s] + Ly[j] > C[s][j] || prev[j] >= 0) continue;
Q[tail++] = Y[j];
prev[j] = s;
if (Y[j] < 0) while (j >= 0) {s = prev[j]; Y[j] = s; k = X[s]; X[s] = j; j = k;}
}
}
if (X[i] >= 0) i ++;
else {
k = (1 << 30);
for (head = 0; head < tail; head++) {
s = Q[head];
for (j = 0; j < ny; j++)
if (prev[j] == -1) k <?= (Lx[s] + Ly[j] - C[s][j]);
}
for (j = 0; j < tail; j++) Lx[Q[j]] -= k;
for (j = 0; j < ny; j++) if (prev[j] >= 0) Ly[j] += k;
}
}
}
8
for (int i = sink; i != source; i = prev[i]) ret = min(ret, cap[prev[i]][i]); //pushf(prev[i],
for (int i = sink; i != source; i = prev[i]) pushf(prev[i], i, ret);
return ret;
}
int mcmf(void) {
int ret, x;
ret = total_cost = 0;
while (x = augment()) ret += x;
return ret;
}
// ***
9
ctype z = INF;
for (x = t; x != s; x = E[prev[x]].x) z = min(z, E[prev[x]].cap);
for (x = t; x != s; x = E[prev[x]].x)
{ E[prev[x]].cap -= z; E[prev[x]^1].cap += z; }
flowVal += z;
flowCost += z * (dist[t] - phi[s] + phi[t]);
for (x = 0; x < N; x++) if (prev[x] != -1) phi[x] += dist[x];
// ***
}
}
};
MinCostMaxFlow - CycleCancellingAlgorithm
1. Repeatedly find negative cost cycles in the graph, using Bellman Ford.
2. Circulate flow across these cycles. Update Graph.
3. Algorithm ends when no cycle is found.
10
best = min(best, w[zj]);
REP (j,n) {
graph[v[j]][prev] = graph[prev][v[j]] += graph[v[zj]][v[j]];
}
v[zj] = v[--n];
break;
}
prev = v[zj];
FOR (j,1,n) if (!a[v[j]]) {
w[j] += graph[v[zj]][v[j]];
}
}
}
return best;
}
Matrix-tree theorem. Let matrix = [ ], where is the number of multiedges between and
, for = , and = deg . Number of spanning trees of a graph is equal to the determinant of a
matrix obtained by deleting any -th row and -th column from . If is a multigraph and is an
edge of , then the number () of spanning trees of satisfies recurrence () = ()+ (/),
when is the multigraph obtained by deleting , and / is the contraction of by (multiple
edges arising from the contraction are preserved.)
Euler tours. Euler tour in an undirected graph exists iff the graph is connected and each vertex has
an even degree. Euler tour in a directed graph exists iff in-degree of each vertex equals its out-degree,
and underlying undirected graph is connected. Construction:
doit(u):
for each edge e = (u, v) in E, do: erase e, doit(v)
prepend u to the list of vertices in the tour
Stable marriages problem. While there is a free man : let be the most-preferred woman to
whom he has not yet proposed, and propose to . If is free, or is engaged to someone whom
she prefers less than , match with , else deny proposal.
Tarjans offline LCA algorithm. (Based on DFS and union-find structure.)
DFS(x):
ancestor[Find(x)] = x
for all children y of x:
DFS(y); Union(x, y); ancestor[Find(x)] = x
seen[x] = true
for all queries {x, y}:
if seen[y] then output "LCA(x, y) is ancestor[Find(y)]"
2-SAT. Build an implication graph with 2 vertices for each variable for the variable and its inverse;
for each clause add edges (, ) and (, ). The formula is satisfiable iff and are in distinct
SCCs, for all . To find a satisfiable assignment, consider the graphs SCCs in topological order from
sinks to sources (i.e. Kosarajus last step), assigning true to all variables of the current SCC (if it
hasnt been previously assigned false), and false to all inverses.
11
Combinatorics
Sums
= ( + 1)/2
=0
2 = ( + 1)(2 + 1)/6
=0
4
5
4
3
=0 = (6+1+ 15 + 10 )/30
1)/( 1)
=0 = (
2
1 + + + = 1/(1 )
= ( + )( + 1)/2
=
3 = 2 ( + 1)2 /4
=0
5
6
5
4
2
=0 = (2 + 6 + 5+1 )/12
+ +2 )/( 1)2
=0 = ( ( + 1)
Binomial coefficients
() (1) (1)
= + 1
Number
Number
Number
Number
of
of
of
of
(+1)
ways to pick a multiset of size from elements:
(
)
( )
-tuples of non-negative integers with sum : +1
, at most : +
1
( 1 )
-tuples of positive integers with sum : 1
( )
lattice paths from (0, 0) to (, ), restricted to east and north steps: +
Harmonic Progression.
2
4
=1 1/ = () + 0.577215664901532 + 1/(2) 1/(12 ) + 1/(120 ) . . .
()
modulo p.
()
( )
mod equals the product of mod where
1 2 . (. . )and 1 2 . . . are the
(1) digits
(4) of and when written in base .
(e.g - 21
mod
17
equals
*
mod 17.)
3
0
3
Number Theory
Linear diophantine equation. + = . Let = gcd(, ). A solution exists iff |. If (0 , 0 )
is any solution, then all solutions are given by (, ) = (0 + , 0 ), Z. To find some solution
(0 , 0 ), use extended GCD to solve 0 + 0 = = gcd(, ), and multiply its solutions by .
Linear diophantine equation in variables: 1 1 + + = has solutions iff gcd(1 , . . . , )|.
To find some solution, let = gcd(2 , . . . , ), solve 1 1 + = , and iterate with 2 2 + = .
Multiplicative inverse of modulo : in + = 1, or ()1 (mod ).
Chinese Remainder Theorem. System (mod ) for = 1, . . . , , with pairwise relatively-
12
1 1
1
+ +
(mod ),
System (mod ), (mod ) has solutions iff (mod ), where = gcd(, ). The
, and equals: + ( )/ + ( )/ (mod ),
solution is unique modulo =
Fermat primes. A Fermat prime is a prime of form 22 + 1. The only known Fermat primes are 3,
5, 17, 257, 65537. A number of form 2 + 1 is prime only if it is a Fermat prime.
Perfect numbers. > 1 is called perfect if it equals sum of its proper divisors and 1. Even is
perfect iff = 21 (2 1) and 2 1 is prime (Mersennes). No odd perfect numbers are yet found.
Carmichael numbers. A positive composite is a Carmichael number (1 1 (mod ) for all
: gcd(, ) = 1), iff is square-free, and for all prime divisors of , 1 divides 1.
+1
Number/sum of divisors.
(11
. . . )
=1 (
+ 1).
(11
. . . )
1
=1 1 .
gcd(,)
() = ()()
. ( ) = 1 ( 1).
| ( ) = .
| () =
(gcd(,))
Eulers theorem. () 1 (mod ), if gcd(, ) = 1.
Wilsons theorem. is prime iff ( 1)! 1 (mod ).
Mobius function. (1) = 1. () = 0, if is not squarefree. () = (1) , if is the
product of
distinct primes. Let , be functions on positive integers. If for all , () = | (), then
13
14
REP(i,N) phi[i] = i; // Calculating euler Totient function.
FOR(i,2,N) if(phi[i] == i) for(int j = i ; j < N ; j += i) phi[j] -= phi[j]/i;
Data - Structures
Segment Tree Fenwick Tree
struct Tournament {
int T[off << 1];
void init(int val) { REP(i,(off<<1)) T[i]=val; }
void update(int x,int val) {
for ( x += off ; x ; x >>= 1 ) T[x] = max(T[x],val);
}
int query( int lo, int hi, int a = 0, int b = off, int x = 1 ) {
if( a >= hi || b <= lo ) return -INF;
if( a >= lo && b <= hi ) return T[x];
return max( query( lo, hi, a, (a+b)/2, 2*x ), query( lo, hi, (a+b)/2, b, 2*x+1 ) );
}
}T;
struct Fenwick {
int F[Max];
void init(int val) { REP(i,Max) F[i] = val; }
void update(int x,int val) {
for ( ++x ; x < Max ; x += x&-x ) F[x] += val ;
}
int query (int x){
int sum = 0;
for ( ++x ; x ; x -= x&-x ) sum += F[x]; return sum;
}
int get_idx(int k) {
int p,ret;
for (p = ret =0;(1 << p) < Max && F[1<<p] < k;++p);--p; // Get the Highest Bit.
for ( ; p >= 0 ; --p )
if ( F[ret | (1<<p)] < k ) ret |= (1<<p) , k -= F[ret];
return ret;
}
}F;
15
Treap(int _val, int _priority, int _maxVal, int _size) {
val = _val;
maxVal = _maxVal;
size = _size;
priority = _priority;
left = right = 0;
}
};
int SZ(Treap* &t) {
return t ? t->size : 0;
}
int MAX(Treap* &t) {
return t ? t->maxVal : 0;
}
void Adjust(Treap* &T) {
T->size
= 1 + SZ(T->left) + SZ(T->right);
T->maxVal = max(T->val, max(MAX(T->left),MAX(T->right)));
}
void rotateLeft(Treap* &T) {
Treap * t = T->left;
T->left = t->right ; Adjust(T);
t->right = T;
Adjust(t);
T = t;
}
void rotateRight(Treap* &T) {
Treap * t = T->right;
T->right = t->left ; Adjust(T);
t->left = T;
Adjust(t);
T = t;
}
void Balance(Treap* &T) {
if(T->left) {
if(T->left->priority > T->priority) rotateLeft(T);
}
if(T->right) {
if(T->right->priority > T->priority) rotateRight(T);
}
}
void insert(Treap* &T, int val, int where, int pri) {
if(!T) T = new Treap(val,pri,val,1);
else {
if(SZ(T->right) >= where) {
insert(T->right,val,where,pri);
}
else if(max(T->val,MAX(T->right)) > val) {
insert(T->right,val,where,pri);
}
else insert(T->left,val,where-SZ(T->right)-1,pri);
Adjust(T); Balance(T);
}
}
16
String Algorithms
int pkmp[MAXN];
bool KMP(char *ptn, int m, char *txt, int n) {
void preKmp(char *ptn, int m) {
int i = 0, j = 0;
int i, j;
preKmp(ptn, m);
i = 0;
while (j < n) {
j = pkmp[0] = -1;
while (i > -1 && ptn[i] != txt[j])
while (i < m) {
i = pkmp[i];
while (j > -1 && ptn[i] != ptn[j])
i++;
j = pkmp[j];
j++;
i++;
j++;
if (i >= m) {
if (ptn[i] == ptn[j])
cout << j <<endl;return true;
pkmp[i] = pkmp[j];
// i = pkmp[i];
else
}
pkmp[i] = j;
}
}
return false;
}
17
Games
Grundy numbers. For a two-player, normal-play (last to move wins) game on a graph (, ):
() = mex({() : (, ) }), where mex() = min{ > 0 : }. is losing iff () = 0.
Sums of games.
Player chooses a game and makes a move in it. Grundy number of a position is xor of grundy
numbers of positions in summed games.
Player chooses a non-empty subset of games (possibly, all) and makes moves in all of them. A
position is losing iff each game is in a losing position.
Player chooses a proper subset of games (not empty and not all), and makes moves in all chosen
ones. A position is losing iff grundy numbers of all games are equal.
Player must move in all games, and loses if cant move in some game. A position is losing if
any of the games is in a losing position.
Mis`
ere Nim. A position with pile sizes 1 , 2 , . . . , > 1, not all equal to 1, is losing iff 1 2
= 0 (like in normal nim.) A position with piles of size 1 is losing iff is odd.
Linear algebra
Determinant of a Matrix
/*
* Determinant of a matrix % p.
* P can be a prime or a power of a single prime.
*/
int b[200][200],n;
int deter(int p) {
int coeff, r2, ret = 1;
REP (i,n) REP (j,n) b[i][j] = mod(b[i][j], p);
REP (i,n) {
if (count_if(b[i] + i, b[i] + n, bind2nd(equal_to<int>(), 0)) == n - i) {
return 0;
}
int g = p;
FOR (j,i,n) g = __gcd(g, b[i][j]);
ret = (int)((((LL)(ret)) * g) % p);
FOR (j,i,n) b[i][j] /= g;
FOR (j,i,n) if (__gcd(b[i][j], p) == 1) {
/* j can act as the pivot */
if (j != i) {
ret = (int)((((LL)(ret)) * (p - 1)) % p);
FOR (k,i,n) swap(b[k][i], b[k][j]);
}
/* now the normal elimination procedure */
FOR (j,i+1,n) {
if (b[i][j]) {
coeff = inverse(b[i][j]);// Get inverse of b[i][i].
//euclide(b[i][i], p, coeff, r2);
18
coeff = (int)((((LL)(coeff)) * b[i][j]) % p);
FOR(k,i,n){
b[k][j]=(int)(b[k][j]-((LL(b[k][i])) * coeff)) % p;
if (b[k][j] < 0) b[k][j] += p;
}
}
}
break;
}
ret = (int)(((LL(ret))*b[i][i])%p);
}
return ret;
}
Notes /
f[A,k] = A + A^2 + A^3 + A^4 + ... + A^k
f[A,k] = f[A,k-1] * (1 + A) - f[A,k-2] * A
int axbmodc(int a, int b,int c) { // Solves a*x = b (mod c)
return a ? (axbmodc(c % a, (a - b % a) % a, a) * c + b) / a : 0;
}
typedef long double LD;
#define MAXN 200
// ret = Inv(arr) Inverse of the matrix -- O(n^3) Gaussean Jordan Elimination
void findInverse(LD arr[MAXN][MAXN],LD ret[MAXN][MAXN],int N){
LD temp[MAXN][2*MAXN];
REP(i,N)REP(j,N)temp[i][j]=arr[i][j]; //not to disturb values in arr
REP(i,N)REP(j,N){
if(i!=j)temp[i][j+N]=0.0l;
else temp[i][j+N]=1.0l;
}
REP(y,N){
int maxRow=y;
FOR(y2,y+1,N) if(fabs(temp[y2][y])>fabs(temp[maxRow][y])) maxRow=y2;
REP(i,2*N)swap(temp[maxRow][i],temp[y][i]);
LD base = temp[y][y];
19
assert(fabs(base)>1e-9);
FOR(y2,y+1,N){
LD factor = temp[y2][y]/base;
REP(x,2*N) temp[y2][x]-=(factor*temp[y][x]);
}
}
for(int y=N-1;y>=0;y--){
LD c=temp[y][y];
REP(y2,y){
for(int x=2*N-1;x>y-1;x--){
temp[y2][x] -= temp[y][x] * temp[y2][y] / c;
}
}
temp[y][y]/=c;
FOR(x,N,2*N)temp[y][x]/=c;
}
REP(i,N)FOR(j,N,2*N)ret[i][j-N]=temp[i][j];
return;
}
20
Geometry
Picks theorem. = /2 + 1, where is the area of a lattice polygon, is number of lattice
points inside it, and is number of lattice points on the boundary. Number of lattice points minus
one on a line segment from (0, 0) and (, ) is gcd(, ).
= + = || || cos()
= = || || sin()
3D: = ( , , )
Line + = through (1 , 1 ) and (2 , 2 ): = 1 2 , = 2 1 , = 1 + 1 .
Half-plane to the left of the directed segment : + > .
Normal vector: (, ). Direction vector: (, ). Perpendicular line: + = .
1
(1 2 2 1 , 1 2 2 1 ).
Point of intersection of 1 + 1 = 1 and 2 + 2 = 2 is 1 2
2 1
Distance from line + + = 0 to point (0 , 0 ) is |0 + 0 + |/ 2 + 2 .
)( )|
Distance from line to (for any dimension): |(||
.
Point-line segment distance:
if (dot(B-A, P-A) < 0) return dist(A,P);
if (dot(A-B, P-B) < 0) return dist(B,P);
return fabs(cross(P,A,B) / dist(A,B));
.
Projection of point onto line is
Projection of (0 , 0 ) onto line + = is (0 , 0 ) +
1
Projection of the origin is 2 +
2 (, ).
1
(, ),
2 +2
where = 0 0 .
Segment-segment intersection. Two line segments intersect if one of them contains an endpoint
of the other segment, or each segment straddles the line, containing the other segment ( straddles
line if and are on the opposite sides of .)
Circle-circle and circle-line intersection.
a = x2 - x1;
b = y2 - y1;
c = [(r1^2 - x1^2 - y1^2) - (r2^2 - x2^2 - y2^2)] / 2;
d = sqrt(a^2 + b^2);
if not |r1 - r2| <= d <= |r1 + r2|, return "no solution"
if d == 0, circles are concentric, a special case
// Now intersecting circle (x1,y1,r1) with line ax+by=c
Normalize line: a /= d; b /= d; c /= d;
// d=sqrt(a^2+b^2)
e = c - a*x1 - b*y1;
h = sqrt(r1^2 - e^2);
// check if r1<e for circle-line test
return (x1, y1) + (a*e, b*e) +/- h*(-b, a);
Circle from 3 points (circumcircle). Intersect two perpendicular bisectors. Line perpendicular
to + = has the form + = . Find by substituting midpoints coordinates.
2
, where , , are lengths of sides, opposite to vertices , , . Radius = ++ .
++
21
3D figures
Sphere
Cone
Volume = 13 2 , lateral surface area = 2 + 2
Computational Geometry
inline T dotp(const Line &l, const complex<T> &p) {
return dotp(l.second - l.first, p - l.first);
}
inline T crossp(const Line &l, const complex<T> &p) {
return crossp(l.second - l.first, p - l.first);
}
pair<Point, long double> getCircle(Point p1, Point p2, Point p3) {
Line L1 = MP(p1,p2);
L1.first = p1 + p2;
L1.first /= 2.0;
L1.second = L1.first + rotate(L1.second - L1.first,90.0);
Line L2(p2,p3);
L2.first = p2 + p3;
L2.first /= 2.0;
L2.second = L2.first + rotate(L2.second - L2.first, 90.0);
Point center = intersectionPointLine(L1,L2);
return MP(center, ABS(center-p1));
}
/*
* Closest pair of points.
* Complexity: O(n*log(n))
* returns INF if number of points < 2.
22
*/
long double closestDistance (Point *p, int n) {
if (n <= 1) return INF;
sort(p, p + n, compare);
map<long double, set<long double> > m;
m[p[0].real()].insert(p[0].imag());
long double h = INF, x, y, dist, hh;
for(int i = 1; i < n; ++i) {
hh = (long double)(sqrt(h) + 1);
map< long double, set<long double> >::iterator sbeg = m.upper_bound(p[i].real() - hh);
for(map<long double, set<long double> >::iterator mit = sbeg; mit != m.end(); ++mit) {
set<long double>::iterator ybeg = (*mit).second.upper_bound( p[i].imag() - hh );
set<long double>::iterator yend = (*mit).second.upper_bound( p[i].imag() + hh - 1);
for (set<long double>::iterator sit = ybeg; sit!=yend; ++sit) {
x = (*mit).first, y = (*sit);
dist = (x - p[i].real())*(x - p[i].real())+
(y - p[i].imag())*(y - p[i].imag());
if (dist < h) {
h = dist;
hh = (long double)(sqrtl(h) + 1);
}
}
}
m[ p[i].real() ].insert(p[i].imag());
}
return sqrtl(h);
}
/*
* Polar angle
* Returns an angle in the range [0, 2*Pi) of a given Cartesian point.
* If the point is (0,0), -1.0 is returned.
*/
long double polarAngle(Point p ) {
if(D_EQ(p.real(), 0) && D_EQ(p.imag(), 0)) return -1.0;
long double res = arg(p);
if ( res < 0 ) {
res += 4.0 * acos(0);
}
return res;
}
/*
* Point inside polygon
* Returns true iff p is inside or on the edge.
* The behavior in case of on the edge can be modified easily..
* Complexity: O(n).
*/
bool pointInPoly(Point p, Point *poly, int n) {
long double ang = 0.0, pi = 2.0*acosl(0);
for( int i = n - 1, j = 0; j < n; i = j++ ) {
Point v = poly[i] - p, w = poly[j] - p;
long double va = polarAngle(v), wa = polarAngle(w), xx = wa - va;
23
if(va < -0.5 || wa
// POINT IS ON
return true;
ang += pi;
continue;
}
if( xx < -pi ) ang
else if( xx > pi )
else ang += xx;
+= xx + 2.0 * pi;
ang += xx - 2.0 * pi;
}
return (ang * ang > 1.0);
}
complex<long double> reflection(const Line &l1,const complex<long double> &p) {
complex<long double> l=l1.second - l1.first;
complex<long double> r(-1.0 * l.imag(), l.real());
long double len = norm(r), d = pointLineDistance(l1, p);
r *= 2.0 * d;
r /= len;
if(D_EQ(pointLineDistance(l1, p + r), d)) return p + r;
return p - r;
}
inline complex<long double> rotate(const complex<long double> &p, long double theta) {
theta = theta * acosl(0) / 90.0;
return complex<long double> (p.real() * cosl(theta) - p.imag() * sinl(theta),
p.real() * sinl(theta) + p.imag() * cosl(theta));
}
long double closestDistance2d(const Segment &s1,const Segment &s2){
Vector u=s1.second-s1.first,v=s2.second-s2.first,w=s1.first-s2.first;
long double a=dotp(u,u),b=dotp(u,v),c=dotp(v,v),d=dotp(u,w),e=dotp(v,w);
long double D=a*c-b*b;
long double sc,sN,sD=D;
long double tc,tN,tD=D;
if(ABS(D) < EPS){
sN=0.0;sD=1.0;tN=e;tD=c;
}
else {
sN=b*e-c*d;
tN=a*e-b*d;
if(sN < 0.0){sN=0.0;tN=e;tD=c;}
else if(sN > sD){sN=sD;tN=e+b;tD=c;}
}
if(tN < 0.0){
tN=0.0;
if(-d < 0.0){sN=0.0;}
else if (-d > a){sN = sD;}
else {sN = -d;sD = a;}
}
else if(tN > tD){
tN=tD;
if ((-d + b) < 0.0){sN = 0;}
else if ((-d + b) > a){sN = sD;}
else {sN = (-d + b);sD = a;}
}
24
sc = ((sN>=0.0?sN:-1.0*sN) < 1e-6 ? 0.0 : sN /
tc = ((tN>=0.0?tN:-1.0*tN) < 1e-6 ? 0.0 : tN /
complex<long double> dP(w.real() + sc*u.real()
w.imag() + sc*u.imag()
return ABS(dP);
sD);
tD);
- tc*v.real(),
- tc*v.imag());
}
long double area(const Triangle &t) {
return ABS(t.a.real() * (t.b.imag() - t.c.imag()) +
t.b.real() * (t.c.imag() - t.a.imag()) +
t.c.real() * (t.a.imag() - t.b.imag())) / 2.0;
}
pair<Point,long double> inCircle(const Triangle &t) {
long double bc = norm(t.c - t.b), ab = norm(t.b - t.a), ac = norm(t.c - t.a);
Point res((t.a.real() * bc + t.b.real() * ac + t.c.real() * ab),
(t.a.imag() * bc + t.b.imag() * ac + t.c.imag() * ab));
res /= (ab + bc + ac);
return make_pair(res, 2.0*area(t) / (ab + bc + ac));
}
Point orthoCenter(const Triangle &t) {
Line bc;bc.first = t.b;bc.second = t.c;
Line A_bc = perpendicular(bc, t.a);
Line ab;ab.first = t.a;ab.second = t.b;
Line C_ab = perpendicular(ab, t.c);
return intersectionPointLine(A_bc, C_ab);
}
pair<Point, long double> circumCircle(const Triangle &t) {
return getCircle(t.a, t.b, t.c);
}
/*
* Returns a triangle with given side lengths.
* The vertices of the new triangle are (0,0), (a, 0) and third point in first quadrant
*/
Triangle triangleFromSideLength(long double a, long double b, long double c) {
Point p1(0.0, 0.0), p2(a, 0.0);
long double cos_theta = (a*a + b*b - c*c) / (2*a*b);
long double sin_theta = sqrtl(1.0 - cos_theta*cos_theta);
Point p3(b*cos_theta, b*sin_theta);
Triangle res = {p1,p2,p3};
return res;
}
inline Point rotate(Point p,double theta){
theta = theta*acos(0)/90;
return Point(p.x*cos(theta) - p.y*sin(theta),p.x*sin(theta)+p.y*cos(theta));
}
// Kunals Stuff
template <class T>
25
class point {
public:
T x, y;
point(T _x, T _y) { x = _x; y = _y; }
point() { x =0; y = 0; }
point operator-(const point &b) { return point(x-b.x, y-b.y); }
T operator*(const point &b) { return (x*b.x + y*b.y); } // Dot Product
T operator^(const point &b) { return x*b.y - y*b.x; }
static double linePointDist(point &a, point &b, point &c, bool isSegment) {
double dis = ((b-a)^(c-a)) / dist(a, b);
if (isSegment) {
T dot1 = (c-b)*(b-a);
if (dot1 > 0) return dist(b, c);
T dot2 = (c-a)*(a-b);
if (dot2 > 0) return dist(c, a);
}
return abs(dis);
}
static double dist(const point &a, const point &b) {
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
static T areaOfPolygon(vector<point> &A) {
int n = SZ(A);
T area = 0;
FOR(i, 1, n-1) {
area += (A[i] - A[0]) ^ (A[i+1] - A[0]);
}
return (abs(area) / 2.0);
}
static point lineIntersection(point &a, point &b, point &c, point &d) {
T A1 = b.y-a.y, B1 = a.x - b.x, C1 = A1*a.x + B1*a.y;
T A2 = d.y-c.y, B2 = c.x - d.x, C2 = A2*c.x + B2*c.y;
T det = A1*B2 - B1*A2;
if (det == 0) { } // Parallel Lines
return point((B2*C1 - B1*C2) / det, (A1*C2 - A2*C1) / det);
}
/*
bool isInBounds(point &a, point &b) {
return (x>=min(a.x,b.x) && x<=max(a.x,b.x) &&
y>=min(a.y,b.y) && y<=max(a.y,b.y));
}
*/
bool isInBounds(point &a, point &b) {
return (min(a.x,b.x)-x<1e-6 && x-max(a.x,b.x)<1e-6 &&
min(a.y,b.y)-y<1e-6 && y-max(a.y,b.y)<1e-6);
}
};