├── src.pdf ├── genpdf ├── footer ├── add_code_to_tex.sh └── header ├── .gitignore ├── hylogo.pdf ├── motivaatiovalas.pdf ├── src ├── other │ ├── xmodmap.txt │ ├── numbers.txt │ ├── flags.txt │ └── bittricks.cpp ├── general.cpp ├── datastructure │ ├── orderedset.cpp │ ├── treap.cpp │ ├── dynamichull.cpp │ ├── HLD.cpp │ └── linkcut.cpp ├── string │ ├── z.cpp │ ├── duval.cpp │ ├── lcparray.cpp │ ├── suffixarray.cpp │ ├── suffixautomaton.cpp │ └── aho-corasick.cpp ├── graph │ ├── unionfind.cpp │ ├── bridges.cpp │ ├── stronglyconnected.cpp │ ├── scalingflow.cpp │ ├── cutvertices.cpp │ ├── dynamicconnectivity.cpp │ ├── rootedtree.cpp │ ├── dinic.cpp │ ├── eulertour.cpp │ ├── matching.cpp │ ├── edmondskarp.cpp │ ├── circulation.cpp │ └── mincostflow.cpp ├── geometry │ ├── anglesort.cpp │ ├── closestpoints.cpp │ ├── welzl.cpp │ ├── convexhull.cpp │ ├── 3dconvexhull.cpp │ ├── minkowskisum.cpp │ ├── halfplaneintersection.cpp │ ├── hullhulltan.cpp │ └── basic.cpp └── math │ ├── diophantine.cpp │ ├── primitiveroot.cpp │ ├── crt.cpp │ ├── pollard-rho.cpp │ ├── miller-rabin.cpp │ ├── fht.cpp │ ├── fft.cpp │ ├── fftmod.cpp │ ├── berlekampmassey.cpp │ ├── gaussjordan.cpp │ └── simplex.cpp ├── codestyle.md ├── genpdf.sh ├── README.md ├── TODO.md └── default.style /src.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Laakeri/contestlib/HEAD/src.pdf -------------------------------------------------------------------------------- /genpdf/footer: -------------------------------------------------------------------------------- 1 | % \end{landscape} 2 | % \end{multicols} 3 | \end{document} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.log 3 | *.aux 4 | *.tex 5 | *.toc 6 | asd 7 | test 8 | -------------------------------------------------------------------------------- /hylogo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Laakeri/contestlib/HEAD/hylogo.pdf -------------------------------------------------------------------------------- /motivaatiovalas.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Laakeri/contestlib/HEAD/motivaatiovalas.pdf -------------------------------------------------------------------------------- /genpdf/add_code_to_tex.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # echo "\\\\newpage" >> $2 4 | echo "\\\\section{$1}" >> $2 5 | echo "\\\\tt{" >> $2 6 | source-highlight -f latexcolor -t 4 -i $1 -o STDOUT >> $2 7 | echo "}" >> $2 8 | -------------------------------------------------------------------------------- /src/other/xmodmap.txt: -------------------------------------------------------------------------------- 1 | // TCR 2 | xmodmap -pke > lol 3 | 49 vasen ylä 4 | 133 windows 5 | less greater less greater bar bar bar 6 | xmodmap lol 7 | xmodmap -pm 8 | xmodmap -e "remove mod4 = Super_L" 9 | (clear mod4) 10 | -------------------------------------------------------------------------------- /codestyle.md: -------------------------------------------------------------------------------- 1 | Each line should be at most 80 characters long 2 | 3 | Lines should be merged if it looks ok and the resulting line is not too long 4 | 5 | Indentation with tabs 6 | 7 | In general minimal number of whitespaces, space after , and before { -------------------------------------------------------------------------------- /src/other/numbers.txt: -------------------------------------------------------------------------------- 1 | // TCR 2 | Primes 3 | 999999937, 999999999999999989, 2013265920268435457 = 2^28*13*223*2587099 + 1 4 | Highly divisible numbers 5 | 840, 32 divisors 6 | 720720, 240 divisors 7 | 735134400, 1344 divisors 8 | 963761198400, 6720 divisors 9 | 866421317361600, 26880 divisors 10 | 897612484786617600, 103680 divisors -------------------------------------------------------------------------------- /genpdf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cat genpdf/header > genpdf/src.tex 4 | grep '// TCR' -R -l src | xargs -I'{}' genpdf/add_code_to_tex.sh {} genpdf/src.tex 5 | cat genpdf/footer >> genpdf/src.tex 6 | pdflatex genpdf/src.tex 7 | pdflatex genpdf/src.tex 8 | pdflatex genpdf/src.tex 9 | pdflatex genpdf/src.tex 10 | rm src.aux src.log src.toc 11 | -------------------------------------------------------------------------------- /src/other/flags.txt: -------------------------------------------------------------------------------- 1 | // TCR 2 | Warnings: -Wall -Wextra -pedantic -Wshadow -Wformat=2 -Wfloat-equal -Wconversion -Wlogical-op -Wcast-qual -Wcast-align 3 | Runtime checks, these might make the code much slower: -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2 -fsanitize=address -fsanitize=undefined -fno-sanitize-recover -fstack-protector 4 | Use these: -std=c++11 -O2 -Wall -Wextra -Wshadow 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # contestlib 2 | 3 | Collection of algorithm implementations for programming contests 4 | 5 | Main purpose of conteslib is to be team reference document for ICPC contests. The team reference document is src.pdf. The files that are included in team reference document begin with // TCR. 6 | 7 | The code is generally ugly because of 25 page limit in the team reference document. 8 | 9 | A graph with n vertices is indexed with integers 1..n. An array/string with n elements is indexed with integers 0..n-1. 10 | -------------------------------------------------------------------------------- /src/general.cpp: -------------------------------------------------------------------------------- 1 | // Standard 2 | #include 3 | #define F first 4 | #define S second 5 | typedef long long ll; 6 | typedef __int128 lll; 7 | typedef long double ld; 8 | using namespace std; 9 | 10 | // GCC extension namespaces 11 | using namespace __gnu_pbds; 12 | using namespace __gnu_cxx; 13 | 14 | // Data structures 15 | #include 16 | #include 17 | 18 | // Numeric 19 | #include 20 | 21 | int main(){ 22 | // Fast I/O: 23 | ios_base::sync_with_stdio(0); 24 | cin.tie(0); 25 | } 26 | -------------------------------------------------------------------------------- /src/datastructure/orderedset.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Sample code on how to use g++ ordered set 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | using namespace __gnu_pbds; 9 | //using namespace pb_ds; 10 | typedef tree, rb_tree_tag, 11 | tree_order_statistics_node_update> ordered_set; 12 | int main() { 13 | ordered_set X; 14 | X.insert(1);X.insert(4); 15 | cout<<*X.find_by_order(1)< s 6 | // z[0]=0 by definition 7 | #include 8 | using namespace std; 9 | vector zAlgo(vector s) { 10 | int n=s.size(); 11 | vector z(n); 12 | int l=0;int r=0; 13 | for (int i=1;ir) { 17 | l=i;r=i+z[i]; 18 | } 19 | } 20 | return z; 21 | } -------------------------------------------------------------------------------- /src/string/duval.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Finds the Lyndon decomposition of a string in O(n) 3 | // Returns the Lyndon substrings as inclusive intervals 4 | #include 5 | using namespace std; 6 | vector > duval(vector s) { 7 | int k=-1; 8 | vector > ret; 9 | while (k+1<(int)s.size()) { 10 | int i=k+1; 11 | for (int j=k+2;;j++){ 12 | if (j>=(int)s.size()||s[i]>s[j]) { 13 | while (k s to string s 4 | #include 5 | using namespace std; 6 | vector lcpArray(vector s, vector sa) { 7 | int n=s.size(), k=0; 8 | vector ra(n), lcp(n); 9 | for (int i=0;ira[(sa[ra[j]]+1)%n]) k=0; 20 | } 21 | return lcp; 22 | } -------------------------------------------------------------------------------- /src/graph/unionfind.cpp: -------------------------------------------------------------------------------- 1 | // Fast union find 2 | // Uses 1-indexing 3 | #include 4 | using namespace std; 5 | 6 | struct unionFind { 7 | vector u; 8 | vector us; 9 | 10 | // Construct union find data structure of n vertices 11 | unionFind(int n) : u(n+1), us(n+1) { 12 | for (int i=1;i<=n;i++) { 13 | u[i]=i; 14 | us[i]=1; 15 | } 16 | } 17 | 18 | // Get the union of x 19 | int get(int x) { 20 | if (x==u[x]) return x; 21 | return u[x]=get(u[x]); 22 | } 23 | 24 | // Union a and b 25 | void un(int a, int b) { 26 | a=get(a); 27 | b=get(b); 28 | if (a!=b) { 29 | if (us[a] 9 | #define X real() 10 | #define Y imag() 11 | using namespace std; 12 | typedef long double ld; 13 | typedef long long ll; 14 | typedef complex co; 15 | bool ccw(co a, co b, co c) { 16 | return ((c-a)*conj(b-a)).Y>0; 17 | } 18 | int ar(co x) { 19 | if (x.Y>=0&&x.X<0) return 1; 20 | if (x.X>=0&&x.Y>0) return 2; 21 | if (x.Y<=0&&x.X>0) return 3; 22 | return 4; 23 | } 24 | bool cp(co p1, co p2) { 25 | if (ar(p1)!=ar(p2)) { 26 | return ar(p1)0; 29 | } -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | #TODO 2 | 3 | * More compact code 4 | * Optimize font size before the final version 5 | 6 | ##Geometry: 7 | * Welzl's algorithm for minimum enclosing circle 8 | * Triangulation 9 | * 3d convex hull 10 | 11 | ##Strings: 12 | * Palindromic tree xD 13 | 14 | ##Graphs: 15 | * Hungarian algorithm 16 | * Min cost arborescence 17 | * Gomory-Hu tree 18 | 19 | ##Data structure 20 | * Some complicated segment tree implementation 21 | * The simple O(n) convex hull trick 22 | 23 | ##Math 24 | * Discrete root http://e-maxx-eng.github.io/algebra/discrete-root.html 25 | * Numerical integration 26 | 27 | ##Test: 28 | * Performance of simplex and write something about it 29 | 30 | ##Other: 31 | * Math formulas? 32 | * TODO lists for practice session and debugging 33 | -------------------------------------------------------------------------------- /src/math/diophantine.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Solves ax+by=c in O(log a+b) time 3 | // Returns {is, {x, y}}, is=0 if there is no solution 4 | // Use __int128 for 64 bit numbers 5 | #include 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | ll ee(ll a, ll b, ll ca, ll cb, ll xa, ll xb, ll&x, ll&y) { 11 | if (cb==0) { 12 | x=xa; 13 | if (b==0) y=0; 14 | else y=(ca-a*xa)/b; 15 | return ca; 16 | } 17 | else return ee(a, b, cb, ca%cb, xb, xa-(ca/cb)*xb, x, y); 18 | } 19 | pair > solve(ll a, ll b, ll c) { 20 | if (c==0) return {1, {0, 0}}; 21 | if (a==0&&b==0) return {0, {0, 0}}; 22 | ll x,y; 23 | ll g=ee(a, b, a, b, 1, 0, x, y); 24 | if (abs(c)%g>0) return {0, {0, 0}}; 25 | return {1, {x*(c/g), y*(c/g)}}; 26 | } -------------------------------------------------------------------------------- /src/math/primitiveroot.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Computes primitive root 3 | // O(sqrt(n)) 4 | #include 5 | using namespace std; 6 | typedef long long ll; 7 | ll pot(ll x, ll p, ll mod) { 8 | if (p==0) return 1; 9 | if (p%2==0) { 10 | x=pot(x, p/2, mod); 11 | return (x*x)%mod; 12 | } 13 | return (x*pot(x, p-1, mod))%mod; 14 | } 15 | ll primitiveRoot(ll p) { 16 | vector fact; 17 | ll phi=p-1;ll n=phi; 18 | for (ll i=2;i*i<=n;i++) { 19 | if (n%i==0) { 20 | fact.push_back(i); 21 | while (n%i==0) n/=i; 22 | } 23 | } 24 | if (n>1) fact.push_back (n); 25 | for (ll res=2;res<=p;res++) { 26 | bool ok = true; 27 | for (int i=0;i<(int)fact.size()&&ok;i++)ok&=pot(res, phi/fact[i], p)!=1; 28 | if (ok) return res; 29 | } 30 | return -1; 31 | } 32 | int main() { 33 | cout< 3 | using namespace std; 4 | int main(){ 5 | // Iterate all submasks in increasing order. Does not list 0. 6 | int mask=13; 7 | for (int sub=0;(sub=(sub-mask)&mask);) { 8 | cout<> (__builtin_ctz(n) + 1)); 21 | cout< 9 | using namespace std; 10 | typedef long long ll; 11 | typedef __int128 lll; 12 | ll ee(ll ca, ll cb, ll xa, ll xb, ll&x) { 13 | if (cb) return ee(cb, ca%cb, xb, xa-(ca/cb)*xb, x); 14 | x = xa; 15 | return ca; 16 | } 17 | pair> crt(vector as, vector ms) { 18 | ll aa = 0, mm = 1, d, a, x; 19 | for (int i = 0; i < (int) as.size(); i++) { 20 | d = ee(ms[i], mm, 1, 0, x); 21 | if ((aa-as[i])%d) return {-1,{0,0}}; 22 | a = ms[i]/d; 23 | mm *= a; 24 | aa = (as[i] + (aa-as[i])*(((lll)a*x)%mm))%mm; 25 | } 26 | if (aa < 0) aa += mm; 27 | return {1, {aa, mm}}; 28 | } -------------------------------------------------------------------------------- /src/graph/bridges.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Finds bridges and 2-edge connected components of graph 3 | // Component of vertex x is c[x] 4 | // Edge is a bridge iff its endpoints are in different components 5 | // Graph in form {adjacent vertex, edge id} 6 | // Uses 1-indexing 7 | #include 8 | #define F first 9 | #define S second 10 | using namespace std; 11 | struct Bridges { 12 | vector c, h; 13 | void dfs(vector >* g, int x, int pe, int d, vector& ns){ 14 | if (h[x]) return; 15 | h[x]=d;ns.push_back(x); 16 | for (auto nx:g[x]) { 17 | if (nx.S!=pe) { 18 | dfs(g, nx.F, nx.S, d+1, ns); 19 | h[x]=min(h[x], h[nx.F]); 20 | } 21 | } 22 | if (h[x]==d) { 23 | while (ns.size()>0) { 24 | int t=ns.back();c[t]=x; 25 | ns.pop_back(); 26 | if (t==x) break; 27 | } 28 | } 29 | } 30 | Bridges(vector >* g, int n) : c(n+1), h(n+1) { 31 | vector ns; 32 | for (int i=1;i<=n;i++) dfs(g, i, -1, 1, ns); 33 | } 34 | }; -------------------------------------------------------------------------------- /src/string/suffixarray.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Suffix array in O((n+S) log n) 3 | // S is the size of alphabet, meaning that 0<=s[i] s to string s. In that case S is 256 5 | // This is CIRCULAR SUFFIX ARRAY. Append $ to the string to make if non circular 6 | #include 7 | using namespace std; 8 | vector suffixArray(vector s, int S) { 9 | int n=s.size();int N=n+S; 10 | vector sa(n), ra(n); 11 | for(int i=0;i nsa(sa), nra(n), cnt(N); 14 | for(int i=0;i=0;i--) sa[--cnt[ra[nsa[i]]]]=nsa[i]; 18 | int r=0; 19 | for(int i=1;i 7 | using namespace std; 8 | typedef long long ll; 9 | typedef __int128 lll; 10 | void step(ll& x, ll n, ll c) {x=(lll)((lll)x*(lll)x+(lll)c)%n;} 11 | void rFactor(ll n, map& r) { 12 | while (n%2==0) { 13 | n/=2;r[2]++; 14 | } 15 | if (n==1) return; 16 | if (isPrime(n)) r[n]++; 17 | else { 18 | while (1) { 19 | ll x=rand()%n;ll y=x; 20 | ll c=rand()%n; 21 | for (ll i=0;i*i<=n;i++) { 22 | step(x, n, c);step(x, n, c);step(y, n, c); 23 | ll g=__gcd(max(x, y)-min(x, y), n); 24 | if (g==n) break; 25 | else if(g>1) { 26 | rFactor(n/g, r); 27 | rFactor(g, r); 28 | return; 29 | } 30 | } 31 | } 32 | } 33 | } 34 | map factor(ll n) { 35 | map ret; 36 | if (n>1) rFactor(n, ret); 37 | return ret; 38 | } -------------------------------------------------------------------------------- /src/math/miller-rabin.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Deterministic Miller-Rabin primality test 3 | // Works for all 64 bit integers 4 | // Support of 128 bit integers is required to test over 32 bit integers 5 | #include 6 | using namespace std; 7 | typedef long long ll; 8 | typedef __int128 lll; 9 | lll powmod(lll a, lll p, lll mod) { 10 | if (p==0) return 1; 11 | if (p%2==0) { 12 | a=powmod(a, p/2, mod); 13 | return (a*a)%mod; 14 | } 15 | return (a*powmod(a, p-1, mod))%mod; 16 | } 17 | bool is_w(ll a, ll even, ll odd, ll p) { 18 | lll u = powmod(a, odd, p); 19 | if (u==1) return 0; 20 | for (ll j=1;j 5 | #define X real() 6 | #define Y imag() 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | typedef long long ll; 11 | typedef complex co; 12 | const ll inf=2e18; 13 | ll csqrt(ll x) { 14 | ll r=sqrt(x); 15 | while (r*rx) r--; 17 | return r; 18 | } 19 | ll sq(ll x) { 20 | return x*x; 21 | } 22 | ll closestPoints(vector points) { 23 | int n=points.size(); 24 | vector > ps(n); 25 | for (int i=0;i > pss; 29 | for (int i=0;id) { 31 | pss.erase({ps[i2].S, ps[i2].F});i2++; 32 | } 33 | auto it=pss.lower_bound({ps[i].S-csqrt(d), -inf}); 34 | for (;it!=pss.end();it++) { 35 | if (sq(it->F-ps[i].S)>d) break; 36 | d=min(d, sq(it->F-ps[i].S)+sq(it->S-ps[i].F)); 37 | } 38 | pss.insert({ps[i].S, ps[i].F}); 39 | } 40 | return d; 41 | } -------------------------------------------------------------------------------- /src/graph/stronglyconnected.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Kosaraju's algorithm for strongly connected components O(V+E) 3 | // Components will be returned in topological order 4 | // Uses 1-indexing 5 | // Returns strongly connected components of the graph in vector ret 6 | // n is the size of the graph, g is the adjacency list 7 | #include 8 | using namespace std; 9 | struct SCC { 10 | vector used; 11 | vector > g2; 12 | void dfs1(vector* g, int x, vector& ns) { 13 | if (used[x]==1) return; 14 | used[x]=1; 15 | for (int nx:g[x]) { 16 | g2[nx].push_back(x); 17 | dfs1(g, nx, ns); 18 | } 19 | ns.push_back(x); 20 | } 21 | void dfs2(int x, vector& co) { 22 | if (used[x]==2) return; 23 | used[x]=2; 24 | co.push_back(x); 25 | for (int nx:g2[x]) dfs2(nx, co); 26 | } 27 | SCC(vector* g, int n, vector >& ret) : used(n+1), g2(n+1) { 28 | vector ns; 29 | for (int i=1;i<=n;i++) dfs1(g, i, ns); 30 | for (int i=n-1;i>=0;i--) { 31 | if (used[ns[i]]!=2) { 32 | ret.push_back(vector()); 33 | dfs2(ns[i], ret.back()); 34 | } 35 | } 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /src/geometry/welzl.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Minimum enclosing circle in expected O(n) time 3 | // Remove duplicate points before using 4 | #include 5 | #define X real() 6 | #define Y imag() 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | typedef long double ld; 11 | typedef complex co; 12 | pair md2(vector R) { 13 | if (R.size()==0) { 14 | return {{0, 0}, -1}; 15 | } else if (R.size()==1) { 16 | return {R[0], 0}; 17 | } else if (R.size()==2) { 18 | return {(R[0]+R[1])/(ld)2.0, hypot(R[0].X-R[1].X, R[0].Y-R[1].Y)/2.0}; 19 | } else { 20 | ld s=(co(0, 1)*(R[0]-R[2])*conj(R[2]-R[1])).Y/((R[0]-R[1])*conj(R[2]-R[1])).Y; 21 | co c=(R[0]+R[1])/(ld)2.0+co(0, 1)*s*((R[0]-R[1])/(ld)2.0); 22 | return {c, hypot(R[0].X-c.X, R[0].Y-c.Y)}; 23 | } 24 | } 25 | pair md(vector& P, int i, vector R) { 26 | if (i==(int)P.size()||R.size()==3) { 27 | return md2(R); 28 | } else { 29 | auto D=md(P, i+1, R); 30 | if (hypot(P[i].X-D.F.X, P[i].Y-D.F.Y)>D.S) { 31 | R.push_back(P[i]); 32 | D=md(P, i+1, R); 33 | } 34 | return D; 35 | } 36 | } 37 | pair minEnclosing(vector P) { 38 | random_shuffle(P.begin(), P.end()); 39 | return md(P, 0, vector()); 40 | } -------------------------------------------------------------------------------- /src/geometry/convexhull.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Computes the convex hull of given set of points in O(n log n) 3 | // Uses Andrew's algorithm 4 | // The points on the edges of the hull are not listed 5 | // Change > to >= in ccw function to list the points on the edges 6 | // Returns points in counterclockwise order 7 | #include 8 | #define X real() 9 | #define Y imag() 10 | using namespace std; 11 | typedef long double ld; 12 | typedef long long ll; 13 | // Coordinate type 14 | typedef ll CT; 15 | typedef complex co; 16 | bool ccw(co a, co b, co c) { 17 | return ((c-a)*conj(b-a)).Y>0; 18 | } 19 | vector convexHull(vector ps) { 20 | auto cmp = [](co a, co b) { 21 | if (a.X==b.X) return a.Y hull;hull.push_back(ps[0]); 29 | for (int d=0;d<2;d++) { 30 | if (d) reverse(ps.begin(), ps.end()); 31 | size_t s=hull.size(); 32 | for (int i=1;is&&!ccw(hull[hull.size()-2],hull.back(),ps[i])) { 34 | hull.pop_back(); 35 | } 36 | hull.push_back(ps[i]); 37 | } 38 | } 39 | hull.pop_back(); 40 | return hull; 41 | } -------------------------------------------------------------------------------- /src/graph/scalingflow.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Scaling flow algorithm for maxflow 3 | // O(E^2 log U), where U is maximum possible flow 4 | // In practice O(E^2) 5 | // Uses 1-indexing 6 | #include 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | typedef long long ll; 11 | struct MaxFlow { 12 | struct e { 13 | int to,r; 14 | ll f; 15 | }; 16 | vector > g; 17 | vector used; 18 | int cc; 19 | ll flow(int x, int t, ll fl, ll miv) { 20 | if (x==t) return fl; 21 | used[x]=cc; 22 | for (auto& nx:g[x]) { 23 | if (used[nx.to]!=cc&&nx.f>=miv) { 24 | ll r=flow(nx.to, t, min(fl, nx.f), miv); 25 | if (r>0) { 26 | nx.f-=r;g[nx.to][nx.r].f+=r; 27 | return r; 28 | } 29 | } 30 | } 31 | return 0; 32 | } 33 | // maxv is maximum expected maxflow 34 | ll getMaxFlow(int source, int sink, ll maxv) { 35 | cc=1;ll r=0;ll k=1; 36 | while (k*2<=maxv) k*=2; 37 | for (;k>0;k/=2) { 38 | while (ll t=flow(source, sink, maxv, k)) { 39 | r+=t;cc++; 40 | } 41 | cc++; 42 | } 43 | return r; 44 | } 45 | void addEdge(int a, int b, ll c) { 46 | g[a].push_back({b, (int)g[b].size(), c}); 47 | g[b].push_back({a, (int)g[a].size()-1, 0}); 48 | } 49 | MaxFlow(int n) : g(n+1), used(n+1) {} 50 | }; -------------------------------------------------------------------------------- /src/datastructure/treap.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Treap implementation with pointers 3 | // Expected running time of split and merge is O(log n) 4 | #include 5 | using namespace std; 6 | typedef struct node* pnode; 7 | struct node { 8 | pnode l,r; 9 | int pr,c; 10 | node() { 11 | l=0;r=0;c=1;pr=rand(); 12 | } 13 | }; 14 | // Returns the size of the subtree t 15 | int cnt(pnode t) { 16 | if (t) return t->c; 17 | return 0; 18 | } 19 | // Updates the size of the subtree t 20 | void upd(pnode t) { 21 | if (t) t->c=cnt(t->l)+cnt(t->r)+1; 22 | } 23 | // Put lazy updates here 24 | void push(pnode t) { 25 | if (t) {}// Lazy update 26 | } 27 | // Merges trees l and r into tree t 28 | void merg(pnode& t, pnode l, pnode r) { 29 | push(l);push(r); 30 | if (!l) t=r; 31 | else if(!r) t=l; 32 | else { 33 | if (l->pr>r->pr) { 34 | merg(l->r, l->r, r);t=l; 35 | } 36 | else { 37 | merg(r->l, l, r->l);t=r; 38 | } 39 | } 40 | upd(t); 41 | } 42 | // Splits tree t into trees l and r 43 | // Size of tree l will be k 44 | void split(pnode t, pnode& l, pnode& r, int k) { 45 | if (!t) { 46 | l=0;r=0;return; 47 | } 48 | else { 49 | push(t); 50 | if (cnt(t->l)>=k) { 51 | split(t->l, l, t->l, k);r=t; 52 | } 53 | else { 54 | split(t->r, t->r, r, k-cnt(t->l)-1);l=t; 55 | } 56 | } 57 | upd(t); 58 | } -------------------------------------------------------------------------------- /src/string/suffixautomaton.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Online suffix automaton construction algorithm 3 | // Time complexity of adding one character is amortized O(1) 4 | #include 5 | using namespace std; 6 | struct SuffixAutomaton { 7 | vector > g; 8 | vector link, len; 9 | int last; 10 | void addC(char c) { 11 | int p=last;int t=link.size(); 12 | link.push_back(0); 13 | len.push_back(len[last]+1); 14 | g.push_back(map()); 15 | while (p!=-1&&g[p].count(c)==0) { 16 | g[p][c]=t;p=link[p]; 17 | } 18 | if (p!=-1) { 19 | int q=g[p][c]; 20 | if (len[p]+1==len[q]) { 21 | link[t]=q; 22 | } 23 | else { 24 | int qq=link.size(); 25 | link.push_back(link[q]); 26 | len.push_back(len[p]+1); 27 | g.push_back(g[q]); 28 | while (p!=-1&&g[p][c]==q) { 29 | g[p][c]=qq;p=link[p]; 30 | } 31 | link[q]=qq;link[t]=qq; 32 | } 33 | } 34 | last=t; 35 | } 36 | SuffixAutomaton() : SuffixAutomaton("") {} 37 | SuffixAutomaton(string s) { 38 | last=0; 39 | g.push_back(map()); 40 | link.push_back(-1); 41 | len.push_back(0); 42 | for (int i=0;i<(int)s.size();i++) addC(s[i]); 43 | } 44 | vector terminals() { 45 | vector t;int p=last; 46 | while (p>0) { 47 | t.push_back(p);p=link[p]; 48 | } 49 | return t; 50 | } 51 | }; -------------------------------------------------------------------------------- /src/math/fht.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Fast Hadamard Transform for computing xor, and, or, convolutions in O(n log n) 3 | // The length of the input vector must be a power of 2 4 | // Works also in mod arithmetic, just remember to handle negative numbers and 5 | // the division in inverse xor 6 | #include 7 | using namespace std; 8 | typedef long long ll; 9 | void fht(vector& a, vector > m) { 10 | for (int len=1;2*len<=(int)a.size();len*=2) { 11 | for (int i=0;i<(int)a.size();i+=2*len) { 12 | for (int j=0;j& a) {fht(a, {{1, 1}, {1, -1}});} 19 | void xorInv(vector& a) { 20 | fht(a, {{1, 1}, {1, -1}}); 21 | for (int i=0;i<(int)a.size();i++) a[i]/=(ll)a.size(); 22 | } 23 | void andTr(vector& a) {fht(a, {{0, 1}, {1, 1}});} 24 | void andInv(vector& a) {fht(a, {{-1, 1}, {1, 0}});} 25 | void orTr(vector& a) {fht(a, {{1, 1}, {1, 0}});} 26 | void orInv(vector& a) {fht(a, {{0, 1}, {1, -1}});} 27 | int main() {// Should print 92 73 78 69 28 | vector a={3, 2, 7, 1}; 29 | vector b={5, 4, 9, 6}; 30 | xorTr(a);xorTr(b); 31 | vector c(4); 32 | for (int i=0;i<4;i++) c[i]=a[i]*b[i]; 33 | xorInv(c); 34 | for (ll t:c) cout< 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | struct Biconnected { 10 | vector cut, h, d, used; 11 | vector > > bg; 12 | vector > es; 13 | int cc; 14 | void dfs(vector* g, int x, int p) { 15 | h[x]=d[x]; 16 | int f=0; 17 | for (int nx:g[x]) { 18 | if (nx!=p) { 19 | if (!used[nx]) es.push_back({x, nx}); 20 | if (d[nx]==0) { 21 | f++;d[nx]=d[x]+1; 22 | int ts=es.size(); 23 | dfs(g, nx, x); 24 | h[x]=min(h[x], h[nx]); 25 | if (h[nx]>=d[x]) { 26 | cut[x]=1; 27 | while ((int)es.size()>=ts) { 28 | auto e=es.back(); 29 | bg[e.F][cc].push_back(e.S); 30 | bg[e.S][cc].push_back(e.F); 31 | used[e.S]=1;used[e.F]=1; 32 | es.pop_back(); 33 | } 34 | used[x]=0;cc++; 35 | } 36 | } 37 | h[x]=min(h[x], d[nx]); 38 | } 39 | } 40 | if (p==0) { 41 | if (f>1) cut[x]=1; 42 | else cut[x]=0; 43 | } 44 | } 45 | Biconnected(vector* g, int n):cut(n+1),h(n+1),d(n+1),used(n+1),bg(n+1){ 46 | cc=1; 47 | for (int i=1;i<=n;i++) { 48 | if (d[i]==0) { 49 | d[i]=1;dfs(g, i, 0); 50 | } 51 | } 52 | } 53 | }; -------------------------------------------------------------------------------- /src/graph/dynamicconnectivity.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // O(n log^2 n) offline solution for the dynamic connectivity problem. 3 | // The purpose of this code is not to be a black box but rather a template 4 | // Optimize memory by using vector& es instead of vector& es 5 | // Uses 1-indexing 6 | #include 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | struct Edge { 11 | int a, b, l, r; 12 | }; 13 | struct DynamicConnectivity { 14 | vector u, us; 15 | vector > st; 16 | int getu(int a) { 17 | if (u[a]==a) return a; 18 | else return getu(u[a]); 19 | } 20 | int uni(int a, int b) { 21 | a=getu(a); 22 | b=getu(b); 23 | if (a==b) return 0; 24 | if (us[a]>us[b]) swap(a, b); 25 | st.push_back({a, b}); 26 | u[a]=b; 27 | us[b]+=us[a]; 28 | return 1; 29 | } 30 | void undo() { 31 | us[st.back().S]-=us[st.back().F]; 32 | u[st.back().F]=st.back().F; 33 | st.pop_back(); 34 | } 35 | void go(int l, int r, vector& es) { 36 | int use=0; 37 | vector nes; 38 | for (auto e:es) { 39 | if (e.l>r||e.r 7 | using namespace std; 8 | typedef long long ll; 9 | const ll isQuery=-(1LL<<62); 10 | struct Line { 11 | ll m, b;int id; 12 | Line(ll m_, ll b_, int id_) : m(m_), b(b_), id(id_) {} 13 | mutable multiset::iterator it,e; 14 | const Line* succ() const { 15 | return next(it)==e ? 0 : &*next(it); 16 | } 17 | bool operator<(const Line& rhs) const { 18 | if (rhs.b!=isQuery) return mb<(s->m-m)*x; 23 | } 24 | }; 25 | struct DynamicHull : public multiset { 26 | bool bad(iterator y) { 27 | auto z=next(y); 28 | if (y==begin()) { 29 | if (z==end()) return 0; 30 | return y->m==z->m&&y->b<=z->b; 31 | } 32 | auto x=prev(y); 33 | if (z==end()) return y->m==x->m&&y->b<=x->b; 34 | return (x->b-y->b)*(z->m-y->m)>=(y->b-z->b)*(y->m-x->m); 35 | } 36 | void insertLine(ll m, ll b, int id) { 37 | auto y=insert({m, b, id}); 38 | y->it=y;y->e=end(); 39 | if (bad(y)) {erase(y);return;} 40 | while (next(y)!=end()&&bad(next(y))) erase(next(y)); 41 | while (y!=begin()&&bad(prev(y))) erase(prev(y)); 42 | } 43 | pair getMax(ll x) { 44 | auto l=*lower_bound({x, isQuery, 0}); 45 | return {l.m*x+l.b, l.id}; 46 | } 47 | }; -------------------------------------------------------------------------------- /src/graph/rootedtree.cpp: -------------------------------------------------------------------------------- 1 | // Build parent array of tree using O(n log n) space 2 | // Query i:th parent in O(log n) time 3 | // Query lca in O(log n) time 4 | // Query distance in O(log n) time 5 | // Uses 1-indexing 6 | #include 7 | using namespace std; 8 | 9 | // This has to be at least ceil(log2(n)) 10 | const int logSize=22; 11 | 12 | struct RootedTree { 13 | 14 | vector d; 15 | vector > p; 16 | 17 | // Dfs for building parent array 18 | void dfs(vector* g, int x, int pp, int dd) { 19 | p[x][0]=pp; 20 | for(int i=1;i* g, int n, int root=1) : d(n+1), p(n+1) { 34 | dfs(g, root, 0, 0); 35 | } 36 | 37 | // Returns the node h edges above x. 38 | // Returns 0 if no such node exists 39 | int parent(int x, int h) { 40 | for (int i=logSize-1;i>=0;i--) { 41 | if ((1<=0;i--) { 54 | if (p[a][i]!=p[b][i]) { 55 | a=p[a][i]; 56 | b=p[b][i]; 57 | } 58 | } 59 | return p[a][0]; 60 | } 61 | 62 | // Returns distance from a to b 63 | int dist(int a, int b) { 64 | int l=lca(a, b); 65 | return d[a]+d[b]-2*d[l]; 66 | } 67 | }; 68 | -------------------------------------------------------------------------------- /src/graph/dinic.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Dinic's algorithm for maxflow 3 | // O(n^2 m) theoretical, really fast (near linear) in practice 4 | // O(m^(3/2)) in unit network graphs 5 | #include 6 | using namespace std; 7 | typedef long long ll; 8 | const ll inf=1e18; 9 | struct MaxFlow { 10 | struct edge { 11 | int a, b; 12 | ll c; 13 | }; 14 | vector es; 15 | vector > g; 16 | vector d, pt; 17 | MaxFlow(int n) : g(n+1), d(n+1), pt(n+1) {} 18 | void addEdge(int a, int b, ll c) { 19 | es.push_back({a, b, c}); 20 | g[a].push_back((int)es.size()-1); 21 | es.push_back({b, a, 0}); 22 | g[b].push_back((int)es.size()-1); 23 | } 24 | bool bfs(int source, int sink) { 25 | queue q({source}); 26 | fill(d.begin(), d.end(), (int)g.size()+1); 27 | d[source]=0; 28 | while(!q.empty()) { 29 | int x=q.front();q.pop(); 30 | if (x==sink) break; 31 | for (int k:g[x]) { 32 | edge& e=es[k]; 33 | if (e.c>0&&d[e.b]>d[e.a]+1) { 34 | d[e.b]=d[e.a]+1; 35 | q.push(e.b); 36 | } 37 | } 38 | } 39 | return d[sink]!=(int)g.size()+1; 40 | } 41 | ll flow(int x, int sink, ll fl=inf) { 42 | if (x==sink||fl==0) return fl; 43 | for (int& i=pt[x];i<(int)g[x].size();i++) { 44 | edge& e=es[g[x][i]]; 45 | edge& oe=es[g[x][i]^1]; 46 | if (d[e.b]==d[e.a]+1) { 47 | if (ll pf=flow(e.b, sink, min(e.c, fl))) { 48 | e.c-=pf; 49 | oe.c+=pf; 50 | return pf; 51 | } 52 | } 53 | } 54 | return 0; 55 | } 56 | ll getMaxFlow(int source, int sink) { 57 | ll r=0; 58 | while (bfs(source, sink)) { 59 | fill(pt.begin(), pt.end(), 0); 60 | while (ll t=flow(source, sink)) r+=t; 61 | } 62 | return r; 63 | } 64 | }; -------------------------------------------------------------------------------- /src/graph/eulertour.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // NOT TESTED PROPERLY?? 3 | // Finds Euler tour of graph in O(E) time 4 | // Parameters are the adjacency list, number of nodes, return value vector, 5 | // and d=1 if the graph is directed 6 | // Return array contains E+1 elements, the first and last elements are same 7 | // Undefined behavior if Euler tour doesn't exist 8 | // Note that Eulerian path can be reduced to Euler tour by adding an edge from 9 | // the last vertex to the first 10 | // In bidirectional graph edges must be in both direction 11 | // Be careful to not add loops twice in case of bidirectional graph 12 | #include 13 | #define F first 14 | #define S second 15 | using namespace std; 16 | struct EulerTour { 17 | int dir; 18 | vector > > g; 19 | vector used; 20 | void dfs(int x, vector& ret) { 21 | int t=x;vector c; 22 | while (1) { 23 | while (used[g[t].back().S]) g[t].pop_back(); 24 | auto nx=g[t].back(); 25 | g[t].pop_back(); 26 | used[nx.S]=1;t=nx.F; 27 | c.push_back(t); 28 | if (t==x) break; 29 | } 30 | for (int a:c) { 31 | ret.push_back(a); 32 | while (g[a].size()>0&&used[g[a].back().S]) g[a].pop_back(); 33 | if (g[a].size()>0) dfs(a, ret); 34 | } 35 | } 36 | EulerTour(vector* og, int n, vector& ret, int d=0):dir(d),g(n+1) { 37 | int i2=0; 38 | for (int i=1;i<=n;i++) { 39 | for (int nx:og[i]) { 40 | if (d==1||nx<=i) { 41 | if (d==0&&nx0) { 49 | ret.push_back(i); 50 | dfs(i, ret); 51 | break; 52 | } 53 | } 54 | } 55 | }; -------------------------------------------------------------------------------- /src/graph/matching.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // General matching in O(n^3) time 3 | #include 4 | using namespace std; 5 | struct Matching { 6 | int n; 7 | vector vLabel, ma, s, u; 8 | queue q; 9 | void rm(int x, int y) { 10 | int m=ma[x];ma[x]=y; 11 | if (ma[m]==x) { 12 | if (vLabel[x]<=n) { 13 | ma[m]=vLabel[x]; 14 | rm(vLabel[x], m); 15 | } 16 | else { 17 | int a=1+(vLabel[x]-n-1)/n; 18 | int b=1+(vLabel[x]-n-1)%n; 19 | rm(a, b);rm(b, a); 20 | } 21 | } 22 | } 23 | void tr(int x) { 24 | for (int i=1;i<=n;i++) s[i]=ma[i]; 25 | rm(x, x); 26 | for (int i=1;i<=n;i++) { 27 | if (ma[i]!=s[i]) u[i]++; 28 | ma[i]=s[i]; 29 | } 30 | } 31 | void rl(int x, int y) { 32 | for (int i=1;i<=n;i++) u[i]=0; 33 | tr(x);tr(y); 34 | for (int i=1;i<=n;i++) { 35 | if (u[i]==1&&vLabel[i]<0) { 36 | vLabel[i]=n+x+(y-1)*n; 37 | q.push(i); 38 | } 39 | } 40 | } 41 | vector > solve(vector* g) { 42 | for (int i=1;i<=n;i++) { 43 | if (ma[i]==0) { 44 | for (int j=1;j<=n;j++) vLabel[j]=-1; 45 | vLabel[i]=0;q.push(i); 46 | while (!q.empty()) { 47 | int x=q.front();q.pop(); 48 | for (int y:g[x]) { 49 | if (ma[y]==0&&i!=y) { 50 | ma[y]=x;rm(x, y); 51 | while (!q.empty()) q.pop(); 52 | break; 53 | } 54 | if (vLabel[y]>=0) { 55 | rl(x, y); 56 | continue; 57 | } 58 | if (vLabel[ma[y]]<0) { 59 | vLabel[ma[y]]=x; 60 | q.push(ma[y]); 61 | } 62 | } 63 | } 64 | } 65 | } 66 | vector > res; 67 | for (int i=1;i<=n;i++) if (ma[i]>i) res.push_back({i, ma[i]}); 68 | return res; 69 | } 70 | Matching(int nn) : n(nn), vLabel(n+1), ma(n+1), s(n+1), u(n+1) {} 71 | }; -------------------------------------------------------------------------------- /src/geometry/3dconvexhull.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // 3d convex hull in O(n^2 log n) 3 | // first 4 points should not be coplanar 4 | struct v3 { 5 | ld x,y,z; 6 | v3() : x(0), y(0), z(0) {} 7 | v3(ld xx, ld yy, ld zz) : x(xx), y(yy), z(zz) {}; 8 | }; 9 | v3 operator+(v3 a, v3 b) { 10 | return v3(a.x+b.x, a.y+b.y, a.z+b.z); 11 | } 12 | v3 operator-(v3 a, v3 b) { 13 | return v3(a.x-b.x, a.y-b.y, a.z-b.z); 14 | } 15 | v3 operator*(v3 a, v3 b) { 16 | return v3(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x); 17 | } 18 | ld operator^(v3 a, v3 b) { 19 | return a.x*b.x+a.y*b.y+a.z*b.z; 20 | } 21 | bool onSameHalfSpace(v3 a, v3 b, v3 p1, v3 p2, v3 p3) { 22 | v3 hlp = (p2-p1)*(p3-p1); 23 | return (hlp^(a-p1))*(hlp^(b-p1))>=0; 24 | } 25 | int n; 26 | v3 pts[1010]; 27 | map,int>,int> convHull; 28 | void toggleHull(int i1, int i2, int i3, int ref) { 29 | if (convHull.count({{i1,i2},i3})) { 30 | convHull.erase({{i1,i2},i3}); 31 | } else convHull[{{i1,i2},i3}]=ref; 32 | } 33 | void makeHull() { 34 | convHull[{{0,1},2}]=3; 35 | convHull[{{0,1},3}]=2; 36 | convHull[{{0,2},3}]=1; 37 | convHull[{{1,2},3}]=0; 38 | for (int i=4;i,pair>> toChange; 40 | for (auto hullFace : convHull) { 41 | int i1=hullFace.F.F.F; 42 | int i2=hullFace.F.F.S; 43 | int i3=hullFace.F.S; 44 | v3 pt1=pts[i1]; 45 | v3 pt2=pts[i2]; 46 | v3 pt3=pts[i3]; 47 | v3 ref=pts[hullFace.S]; 48 | if (!onSameHalfSpace(pts[i],ref,pt1,pt2,pt3)) { 49 | toChange.push_back({{i1,i2},{i,i3}}); 50 | toChange.push_back({{i1,i3},{i,i2}}); 51 | toChange.push_back({{i2,i3},{i,i1}}); 52 | toChange.push_back({{i1,i2},{i3,i}}); 53 | } 54 | } 55 | for (auto diff : toChange) { 56 | toggleHull(diff.F.F,diff.F.S,diff.S.F, diff.S.S); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /src/graph/edmondskarp.cpp: -------------------------------------------------------------------------------- 1 | // Edmonds Karp algorithm for maxflow O(V E^2) or O(f E) 2 | // f is the capacity network and the actual flow can be found in it 3 | // If edges for both directions are used finding actual flow is harder 4 | // Uses 1-indexing 5 | #include 6 | #define F first 7 | #define S second 8 | using namespace std; 9 | typedef long long ll; 10 | const int inf=2e9; 11 | struct MaxFlow { 12 | vector > f; 13 | vector > g; 14 | vector fr; 15 | vector used; 16 | int flow(int so, int si, int n) { 17 | queue, int> > bfs; 18 | bfs.push({{0, so}, inf}); 19 | int fl=0; 20 | while(!bfs.empty()) { 21 | auto x=bfs.front(); 22 | bfs.pop(); 23 | if (used[x.F.S]) continue; 24 | used[x.F.S]=1; 25 | fr[x.F.S]=x.F.F; 26 | if (x.F.S==si) { 27 | fl=x.S; 28 | break; 29 | } 30 | for (int nx:g[x.F.S]) { 31 | if (f[x.F.S][nx]>0) { 32 | bfs.push({{x.F.S, nx}, min(x.S, f[x.F.S][nx])}); 33 | } 34 | } 35 | } 36 | for (int i=1;i<=n;i++) used[i]=0; 37 | if (fl>0) { 38 | int x=si; 39 | while (fr[x]>0) { 40 | f[x][fr[x]]+=fl; 41 | f[fr[x]][x]-=fl; 42 | x=fr[x]; 43 | } 44 | return fl; 45 | } 46 | return 0; 47 | } 48 | 49 | ll getMaxFlow(int source, int sink) { 50 | int n=fr.size()-1; 51 | for (int i=1;i<=n;i++) { 52 | g[i].clear(); 53 | for (int ii=1;ii<=n;ii++) { 54 | if (f[i][ii]!=0||f[ii][i]!=0) { 55 | g[i].push_back(ii); 56 | } 57 | } 58 | } 59 | ll r=0; 60 | while (1) { 61 | int fl=flow(source, sink, n); 62 | if (fl==0) break; 63 | r+=(ll)fl; 64 | } 65 | return r; 66 | } 67 | 68 | void addEdge(int a, int b, int c) { 69 | f[a][b]=c; 70 | } 71 | 72 | MaxFlow(int n) : f(n+1), g(n+1), fr(n+1), used(n+1) { 73 | for (int i=1;i<=n;i++){ 74 | f[i]=vector(n+1); 75 | } 76 | } 77 | }; -------------------------------------------------------------------------------- /src/math/fft.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Fast Fourier transform and convolution using it 3 | // O(n log n) 4 | // Is accurate with integers if the numbers of the result array are <= 4e15 5 | // Also accurate if input <= 1e6 and the lengths of input arrays are 2e5 6 | // Can be speed up by a factor of 2 by implementing the complex class 7 | #include 8 | using namespace std; 9 | typedef long double ld; 10 | typedef long long ll; 11 | typedef complex co; 12 | const ld PI=atan2((ld)0, (ld)-1); 13 | void fft(vector&a, int n, int k) { 14 | vector ww(n); 15 | ww[1]=co(1, 0); 16 | for (int t=0;t conv(const vector& a, const vector& b) { 37 | int as=a.size(), bs=b.size(); 38 | if (as*bs==0) return {}; 39 | int k=0; 40 | while ((1< c(n+1); 43 | for (int i=0;i r(as+bs-1); 55 | for (int i=0;i a={3, 2, 7}; 60 | vector b={4, 1}; 61 | vector c=conv(a, b); 62 | for (ll t:c) cout< 6 | using namespace std; 7 | typedef long long ll; 8 | template struct Circulation { 9 | struct Edge { 10 | int a, b; 11 | ll ca, co; 12 | } es[E*2]; 13 | int eu=0,cookie=1; 14 | int how[V+1], good[V+1], bio[V+1]; 15 | ll dist[V+1]; 16 | void addEdge(int from, int to, ll ca, ll co) { 17 | es[eu++]={from, to, ca, co}; 18 | es[eu++]={to, from, 0, -co}; 19 | } 20 | void reset() { 21 | for (int i=1;i<=V;i++) { 22 | dist[i]=0;how[i]=-1;bio[i]=0; 23 | } 24 | } 25 | bool relax() { 26 | bool ret=false; 27 | for (int e=0;e=0?0:cycle(x, true); 59 | } 60 | ll minCostCirculation() { 61 | reset(); 62 | ll cost=0; 63 | for (int step=0;step<2*V;step++) { 64 | if (step == V) reset(); 65 | if (!relax()) continue; 66 | for (int i=1;i<=V;i++) good[i]=true; 67 | for (int i=1;i<=V;i++) if (ll w=push(i)) {cost+=w;step=0;} 68 | } 69 | return cost; 70 | } 71 | }; -------------------------------------------------------------------------------- /src/datastructure/HLD.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Builds Heavy-light decomposition of tree in O(n) time 3 | // getPath returns decomposed path from a to b in a vector which contains 4 | // {{u, v}, {index[u], index[v]}} index[u]<=index[v], depth[u]<=depth[v] 5 | // lca(a, b) is in the last path of the vector 6 | // Uses 1-indexing 7 | #include 8 | using namespace std; 9 | struct HLD { 10 | vector aps, pRoot, pLI, pRI, nPath, nPathId, p; 11 | int index; 12 | void dfs1(vector* g, int x) { 13 | aps[x]=1; 14 | for (int nx:g[x]) { 15 | if (nx!=p[x]) { 16 | p[nx]=x;dfs1(g, nx); 17 | aps[x]+=aps[nx]; 18 | } 19 | } 20 | } 21 | void dfs2(vector* g, int x, int path, int pi) { 22 | if (path==-1) { 23 | path=pRoot.size(); 24 | pRoot.push_back(x); 25 | pLI.push_back(index); 26 | pRI.push_back(index); 27 | } 28 | nPath[x]=path; 29 | nPathId[x]=pi; 30 | pRI[path]=index++; 31 | int ma=0; 32 | for (int nx:g[x]){ 33 | if (nx!=p[x]&&aps[nx]>aps[ma]) ma=nx; 34 | } 35 | if (ma) dfs2(g, ma, path, pi+1); 36 | for (int nx:g[x]){ 37 | if (nx!=p[x]&&nx!=ma) dfs2(g, nx, -1, 0); 38 | } 39 | } 40 | HLD(vector* g, int n) : aps(n+1), nPath(n+1), nPathId(n+1), p(n+1) { 41 | index=0;dfs1(g, 1); 42 | dfs2(g, 1, -1, 0); 43 | } 44 | vector, pair > > getPath(int a, int b) { 45 | vector, pair > > ret; 46 | while (nPath[a]!=nPath[b]) { 47 | int pa=nPath[a]; 48 | int pb=nPath[b]; 49 | if (pa>pb) { 50 | ret.push_back({{pRoot[pa], a}, {pLI[pa], pLI[pa]+nPathId[a]}}); 51 | a=p[pRoot[pa]]; 52 | } 53 | else { 54 | ret.push_back({{pRoot[pb], b}, {pLI[pb], pLI[pb]+nPathId[b]}}); 55 | b=p[pRoot[pb]]; 56 | } 57 | } 58 | int pa=nPath[a]; 59 | if (nPathId[a]>nPathId[b]) swap(a, b); 60 | ret.push_back({{a, b}, {pLI[pa]+nPathId[a], pLI[pa]+nPathId[b]}}); 61 | return ret; 62 | } 63 | }; -------------------------------------------------------------------------------- /src/string/aho-corasick.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Aho-Corasick algorithm 3 | // Building of automaton is O(L) where L is total length of dictionary 4 | // Matching is O(n + number of matches), O(n sqrt(L)) in the worst case 5 | // Add dictionary using addString and then use pushLinks 6 | #include 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | struct AhoCorasick { 11 | vector > g; 12 | vector link, tlink, te; 13 | // Use 1-indexing in id 14 | void addString(const string& s, int id) { 15 | int tn=0; 16 | for (int i=0;i<(int)s.size();i++) { 17 | if (g[tn][s[i]]==0) { 18 | g[tn][s[i]]=g.size(); 19 | g.push_back(map()); 20 | link.push_back(0); 21 | tlink.push_back(0); 22 | te.push_back(0); 23 | } 24 | tn=g[tn][s[i]]; 25 | } 26 | te[tn]=id; 27 | } 28 | void pushLinks() { 29 | queue bfs; 30 | bfs.push(0); 31 | while (!bfs.empty()) { 32 | int x=bfs.front(); 33 | bfs.pop(); 34 | for (auto nx:g[x]) { 35 | int l=link[x]; 36 | while (l!=-1&&g[l].count(nx.F)==0) l=link[l]; 37 | if (l!=-1) link[nx.S]=g[l][nx.F]; 38 | bfs.push(nx.S); 39 | if (te[link[nx.S]]) tlink[nx.S]=link[nx.S]; 40 | else tlink[nx.S]=tlink[link[nx.S]]; 41 | } 42 | } 43 | } 44 | // Returns matches {id, endpos} 45 | vector > match(const string& s) { 46 | int tn=0; 47 | vector > re; 48 | for (int i=0;i<(int)s.size();i++) { 49 | while (tn!=-1&&g[tn].count(s[i])==0) tn=link[tn]; 50 | if (tn==-1) tn=0; 51 | tn=g[tn][s[i]]; 52 | int f=tlink[tn]; 53 | if (te[tn]) re.push_back({te[tn], i}); 54 | while (f) { 55 | re.push_back({te[f], i}); 56 | f=tlink[f]; 57 | } 58 | } 59 | return re; 60 | } 61 | AhoCorasick() { 62 | g.push_back(map()); 63 | link.push_back(-1); 64 | tlink.push_back(0); 65 | te.push_back(0); 66 | } 67 | }; -------------------------------------------------------------------------------- /default.style: -------------------------------------------------------------------------------- 1 | bgcolor "white"; // the background color for documents 2 | context gray; // the color for context lines (when specified with line ranges) 3 | 4 | keyword "Blue" b; // for language keywords 5 | type "NavyBlue" f; // for basic types 6 | usertype "NavyBlue" f; // for user defined types 7 | string red f ; // for strings and chars 8 | regexp orange f ; // for strings and chars 9 | specialchar pink f ; // for special chars, e.g., \n, \t, \\ 10 | comment gray f, noref; // for comments 11 | number purple ; // for literal numbers 12 | preproc "Green" b ; // for preproc directives (e.g. #include, import) 13 | symbol darkred ; // for simbols (e.g. <, >, +) 14 | function black b; // for function calls and declarations 15 | cbracket red; // for block brackets (e.g. {, }) 16 | todo bg:cyan b; // for TODO and FIXME 17 | code bg:brightgreen b; // for code snippets 18 | 19 | //Predefined variables and functions (for instance glsl) 20 | predef_var darkblue ; 21 | predef_func darkblue b ; 22 | 23 | // for OOP 24 | classname darkgreen; // for class names, e.g., in Java and C++ 25 | 26 | // line numbers 27 | linenum black f; 28 | 29 | // Internet related 30 | url blue u, f; 31 | 32 | // other elements for ChangeLog and Log files 33 | date blue b ; 34 | time, file darkblue b ; 35 | ip, name darkgreen ; 36 | 37 | // for Prolog, Perl... 38 | variable darkgreen ; 39 | 40 | // explicit for Latex 41 | italics darkgreen i; 42 | bold darkgreen b; 43 | underline darkgreen u; 44 | fixed green f; 45 | argument darkgreen; 46 | optionalargument purple; 47 | math orange; 48 | bibtex blue; 49 | 50 | // for diffs 51 | oldfile orange; 52 | newfile darkgreen; 53 | difflines blue; 54 | 55 | // for css 56 | selector purple; 57 | property blue; 58 | value darkgreen i; 59 | 60 | // for oz 61 | atom orange; 62 | meta i; 63 | 64 | // for file system 65 | path orange; 66 | 67 | // for C (or other language) labels 68 | label teal b; 69 | 70 | // for errors 71 | error purple; 72 | warning darkgreen; 73 | 74 | // for feature (Cucumber) files 75 | cuketag green ; 76 | gherken blue ; 77 | given red ; 78 | when cyan ; 79 | then yellow ; 80 | and_but pink ; 81 | table gray ; 82 | -------------------------------------------------------------------------------- /src/math/fftmod.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Precise FFT modulo mod 3 | #include 4 | using namespace std; 5 | typedef long long ll; 6 | typedef long long lll; 7 | // Number of form (2^25)*k+1 8 | const lll mod=2113929217; // between 2*10^9 and 2^31 9 | // Number whose order mod mod is 2^25 10 | const lll root=1971140334; 11 | const lll root_pw=1<<25; 12 | // 128 bit 13 | // typedef __int128 lll; 14 | // const lll mod=2013265920268435457; // between 2*10^18 and 2^61 15 | // const lll root=1976010382590097340; 16 | // const lll root_pw=1<<28; 17 | lll pot(lll x, lll p) { 18 | if (p==0) return 1; 19 | if (p%2==0) { 20 | x=pot(x, p/2); 21 | return (x*x)%mod; 22 | } 23 | return (x*pot(x, p-1))%mod; 24 | } 25 | lll inv(lll x) { 26 | return pot(x, mod-2); 27 | } 28 | vector fft (vector a, int d) { 29 | lll root_1=inv(root); 30 | int n=(int)a.size(); 31 | for (int i=1,j=0;i>1; 33 | for (;j>=bit;bit>>=1) j-=bit; 34 | j+=bit; 35 | if (i=0) a[i+j+len/2]=u-v; 49 | else a[i+j+len/2]=u-v+mod; 50 | w=(w*wlen)%mod; 51 | } 52 | } 53 | } 54 | if (d==-1) { 55 | lll nrev=inv(n); 56 | for (int i=0;i conv(const vector& a, const vector& b) { 61 | int as=a.size(), bs=b.size(); 62 | int n=1; 63 | while (n aa(n*2), bb(n*2); 65 | for (int i=0;i c(2*n); 69 | for (int i=0;i<2*n;i++) c[i]=(aa[i]*bb[i])%mod; 70 | c=fft(c, -1); 71 | c.resize(as+bs-1); 72 | return c; 73 | } 74 | int main() { 75 | // Shoud print 12 11 30 7 76 | vector a={3, 2, 7}; 77 | vector b={4, 1}; 78 | vector c=conv(a, b); 79 | for (lll t:c) { 80 | cout<<(ll)t< 7 | #define X real() 8 | #define Y imag() 9 | #define F first 10 | #define S second 11 | using namespace std; 12 | typedef long double ld; 13 | typedef long long ll; 14 | typedef complex co; 15 | ll ccw(co a, co b, co c) { 16 | return ((c-a)*conj(b-a)).Y; 17 | } 18 | int ar(co x) { 19 | if (x.Y>=0&&x.X<0) return 1; 20 | if (x.X>=0&&x.Y>0) return 2; 21 | if (x.Y<=0&&x.X>0) return 3; 22 | return 4; 23 | } 24 | bool cp(pair > p1, pair > p2) { 25 | if (ar(p1.F)!=ar(p2.F)) { 26 | return ar(p1.F)p2.S; 31 | } 32 | return ccw({0, 0}, p2.F, p1.F)>0; 33 | } 34 | vector minkowski(vector& a, vector& b) { 35 | int n=a.size(); 36 | int m=b.size(); 37 | if (n==0) return b; 38 | if (m==0) return a; 39 | if (n==1) { 40 | vector ret(m); 41 | for (int i=0;i ret(n); 48 | for (int i=0;i > > pp; 54 | int f1=0; 55 | int f2=0; 56 | for (int i=0;i ret(pp.size()); 85 | for (int i=0;i<(int)pp.size();i++) { 86 | ret[i]=s;s+=pp[i].F; 87 | } 88 | return ret; 89 | } -------------------------------------------------------------------------------- /src/graph/mincostflow.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Find minimum-cost k-flow 3 | // O(VE) normalizing and O(E log V) for each augmenting path 4 | // getKFlow augments at most k flow and returns {flow, cost} 5 | // Uses 1-indexing 6 | #include 7 | #define F first 8 | #define S second 9 | using namespace std; 10 | typedef long long ll; 11 | const ll inf=1e18; 12 | template struct MinCostFlow { 13 | struct Edge { 14 | int a, b; 15 | ll ca, co; 16 | } es[E*2]; 17 | int eu=0,nmz=0; 18 | vector g[V+1]; 19 | ll p[V+1],d[V+1]; 20 | int fr[V+1],u[V+1]; 21 | void addEdge(int a, int b, ll ca, ll co) { 22 | nmz=0; 23 | es[eu++]={a, b, ca, co}; 24 | es[eu++]={b, a, 0, -co}; 25 | g[a].push_back(eu-2); 26 | g[b].push_back(eu-1); 27 | } 28 | void normalize(int source) { 29 | if (nmz) return;nmz=1; 30 | for (int i=1;i<=V;i++) { 31 | p[i]=inf;u[i]=0; 32 | } 33 | p[source]=0; 34 | queue q;q.push(source); 35 | while (!q.empty()){ 36 | int x=q.front(); 37 | u[x]=0;q.pop(); 38 | for (int e:g[x]) { 39 | if (es[e].ca>0&&p[x]+es[e].co flow(int source, int sink, ll mf) { 57 | priority_queue > dij; 58 | for (int i=1;i<=V;i++) { 59 | u[i]=0;fr[i]=-1;d[i]=inf; 60 | } 61 | d[source]=0; 62 | dij.push({0, source}); 63 | while (!dij.empty()) { 64 | auto x=dij.top();dij.pop(); 65 | if (u[x.S]) continue; 66 | u[x.S]=1; 67 | for (int e:g[x.S]) { 68 | ll nd=d[x.S]+es[e].co+p[x.S]-p[es[e].b]; 69 | if (es[e].ca>0&&nd getKFlow(int source, int sink, ll k) { 87 | ll fl=0;ll co=0; 88 | normalize(source); 89 | while (1) { 90 | pair t=flow(source, sink, k); 91 | fl+=t.F;k-=t.F;co+=t.S; 92 | if (k==0||t.F==0) break; 93 | } 94 | return {fl, co}; 95 | } 96 | }; -------------------------------------------------------------------------------- /src/datastructure/linkcut.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Link/cut tree. All operations are amortized O(log n) time 3 | // This implementation supports finding minimum value on a path (usual MST case) 4 | // evert(x) makes x the root 5 | // expose(x, y) now the path from x to y is in the tree whose root is x 6 | #include 7 | using namespace std; 8 | struct Node { 9 | Node* c[2], *p; 10 | int id, rev; 11 | int v, mv; 12 | int isr() { 13 | return !p||(p->c[0]!=this&&p->c[1]!=this); 14 | } 15 | int dir() { 16 | return p->c[1]==this; 17 | } 18 | void upd(){ 19 | mv=v; 20 | if (c[0]) mv=min(mv, c[0]->mv); 21 | if (c[1]) mv=min(mv, c[1]->mv); 22 | } 23 | void setc(Node* s, int d) { 24 | c[d]=s; 25 | if (s) s->p=this; 26 | upd(); 27 | } 28 | void push() { 29 | if (rev) { 30 | swap(c[0], c[1]); 31 | if (c[0]) c[0]->rev^=1; 32 | if (c[1]) c[1]->rev^=1; 33 | rev=0; 34 | } 35 | } 36 | Node(int i, int val) : id(i), v(val), mv(val) { 37 | c[0]=0;c[1]=0;p=0;rev=0; 38 | } 39 | }; 40 | struct LinkCut { 41 | void rot(Node* x) { 42 | Node* p=x->p;int d=x->dir(); 43 | if (!p->isr()) p->p->setc(x, p->dir()); 44 | else x->p=p->p; 45 | p->setc(x->c[!d], d);x->setc(p, !d); 46 | } 47 | void pp(Node* x) { 48 | if (!x->isr()) pp(x->p); 49 | x->push(); 50 | } 51 | void splay(Node* x) { 52 | pp(x); 53 | while (!x->isr()) { 54 | if (x->p->isr()) rot(x); 55 | else if(x->dir()==x->p->dir()) { 56 | rot(x->p);rot(x); 57 | } 58 | else { 59 | rot(x);rot(x); 60 | } 61 | } 62 | } 63 | Node* expose(Node* x) { 64 | Node* q=0; 65 | for (;x;x=x->p) { 66 | splay(x);x->c[1]=q;x->upd();q=x; 67 | } 68 | return q; 69 | } 70 | void evert(Node* x) { 71 | x=expose(x);x->rev^=1;x->push(); 72 | } 73 | void link(Node* x, Node* y) { 74 | evert(x);evert(y);splay(y);x->setc(y, 1); 75 | } 76 | void expose(Node* x, Node* y) { 77 | evert(x);expose(y);splay(x); 78 | } 79 | void cut(Node* x, Node* y) { 80 | expose(x, y);x->c[1]=0;x->upd();y->p=0; 81 | } 82 | int rootid(Node* x) { 83 | expose(x);splay(x); 84 | while(x->c[0]) { 85 | x=x->c[0];x->push(); 86 | } 87 | splay(x); 88 | return x->id; 89 | } 90 | Node* getMin(Node* x) { 91 | if (x->v==x->mv) { 92 | splay(x); 93 | return x; 94 | } 95 | if (x->c[0]&&x->c[0]->mv==x->mv) return getMin(x->c[0]); 96 | else return getMin(x->c[1]); 97 | } 98 | Node* getMinP(Node* x, Node* y) { 99 | expose(x, y); 100 | return getMin(x); 101 | } 102 | }; -------------------------------------------------------------------------------- /src/geometry/halfplaneintersection.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // getHPI returns the points of the half place intersection in the ccw order 3 | // The allowed half plane is the left side of the p1 -> p2 vector 4 | // maxD defines the bounding square so that the resulting polygon is never infinite 5 | // May return many points even though the intersection is empty. 6 | // Compute the area to check the emptiness. 7 | // May return duplicate points and is generally kind of numerically unstable. 8 | // coordinates<=1e6: eps in [1e-12, 1e-7] for ld and eps in [1e-9, 1e-7] for double 9 | #include 10 | #define X real() 11 | #define Y imag() 12 | using namespace std; 13 | typedef long double ld; 14 | typedef complex co; 15 | const ld eps=1e-12; 16 | const ld maxD=1e8; 17 | ld ccw(co a, co b) { 18 | return (b*conj(a)).Y; 19 | } 20 | int ar(co x) { 21 | if (x.Y>=0&&x.X<0) return 1; 22 | if (x.X>=0&&x.Y>0) return 2; 23 | if (x.Y<=0&&x.X>0) return 3; 24 | return 4; 25 | } 26 | bool cp(co p1, co p2) { 27 | if (ar(p1)!=ar(p2)) return ar(p1)>ar(p2); 28 | return ccw(p2, p1)<0; 29 | } 30 | struct hp_t { 31 | co a, b; 32 | hp_t(co p1, co p2) { 33 | a=p1; 34 | b=(p2-p1)/abs(p2-p1); 35 | } 36 | ld d(co p) const { 37 | return ccw(b, p-a); 38 | } 39 | bool operator==(const hp_t& o) const { 40 | return abs(b.X-o.b.X) getHPI(vector hp) { 55 | hp.push_back({{-maxD, -maxD}, {maxD, -maxD}}); 56 | hp.push_back({{maxD, -maxD}, {maxD, maxD}}); 57 | hp.push_back({{maxD, maxD}, {-maxD, maxD}}); 58 | hp.push_back({{-maxD, maxD}, {-maxD, -maxD}}); 59 | sort(hp.begin(), hp.end()); 60 | hp.erase(unique(hp.begin(), hp.end()), hp.end()); 61 | int del=0; 62 | vector p; 63 | for (int i=1;i<(int)hp.size();i++) { 64 | while ((int)p.size()>del&&hp[i].d(p.back())del&&hp[i].d(p[del])-eps) { 69 | p.push_back(np); 70 | hp[p.size()]=hp[i]; 71 | } 72 | } 73 | rotate(p.begin(), p.begin()+del, p.end()); 74 | rotate(hp.begin(), hp.begin()+del, hp.begin()+p.size()+1); 75 | p.resize((int)p.size()-del); 76 | if (p.empty()) return p; 77 | p.push_back(getI(hp[0], hp[p.size()])); 78 | return p; 79 | } -------------------------------------------------------------------------------- /src/math/berlekampmassey.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Berlekamp massey 3 | // Give a sequence of integers in constructor and query with get(index) 4 | // Use just the solve to get the coefficients of the recursion 5 | // remember to negate the coefficients 6 | #include 7 | using namespace std; 8 | typedef long long ll; 9 | ll powmod(ll a, ll p, ll modd) { 10 | if (p==0) return 1; 11 | if (p%2==0) { 12 | a=powmod(a, p/2, modd); 13 | return (a*a)%modd; 14 | } 15 | return (a*powmod(a, p-1, modd))%modd; 16 | } 17 | ll invp(ll a, ll p) { 18 | return powmod(a, p - 2, p); 19 | } 20 | vector solve(vector S, ll mod) { 21 | vector C = {1}; 22 | vector B = {1}; 23 | ll L = 0;ll m = 1;ll b = 1;ll N = S.size(); 24 | for (ll i = 0; i < N; i++) { 25 | ll d = S[i]; 26 | for (ll j = 1; j <= L; j++) { 27 | d += C[j]*S[i - j];d %= mod; 28 | } 29 | if (d == 0) { 30 | m++; 31 | } else if (2*L <= i) { 32 | vector T = C; 33 | ll a = (invp(b, mod)*d)%mod; 34 | for (int j=0;j > mat; 57 | vector seq; 58 | ll mod; 59 | vector > mul(vector > a, vector > b) { 60 | int n=a.size(); 61 | vector > ret(n); 62 | for (int i=0;i > pot(vector > m, ll p) { 75 | if (p==1) return m; 76 | if (p%2==0) { 77 | m=pot(m, p/2); 78 | return mul(m, m); 79 | } 80 | else { 81 | return mul(m, pot(m, p-1)); 82 | } 83 | } 84 | ll get(ll index) { 85 | if (index<(ll)mat.size()) { 86 | return seq[index]; 87 | } 88 | vector > a=pot(mat, index-(ll)mat.size()+1); 89 | ll v=0; 90 | for (int i=0;i<(int)mat.size();i++) { 91 | v+=a[0][i]*seq[(int)mat.size()-i-1]; 92 | v%=mod; 93 | } 94 | return v; 95 | } 96 | LinearRecurrence(vector S, ll mod_) { 97 | seq=S; 98 | mod=mod_; 99 | vector C=solve(S, mod); 100 | int n=C.size()-1; 101 | mat.resize(n); 102 | for (int i=0;i 10 | using namespace std; 11 | typedef long long ll; 12 | typedef long double ld; 13 | const ld eps=1e-12; 14 | // Using doubles 15 | int gaussD (vector > a, vector& ans) { 16 | int n=(int)a.size(); 17 | int m=(int)a[0].size()-1; 18 | vector where(m,-1); 19 | for (int col=0,row=0;colabs(a[sel][col])) sel=i; 23 | } 24 | if (abs(a[sel][col])eps) return 0; 43 | } 44 | for (int i=0;i > a, int n, int m, bitset& ans) { 53 | vector where (m, -1); 54 | for (int col=0,row=0;col > d(3); 85 | d[0]={3, 3, -15, 9}; 86 | d[1]={1, 0, -2, 1}; 87 | d[2]={2, -1, -1, 0}; 88 | vector da; 89 | cout< r1("0110"); 94 | bitset r2("1101"); 95 | bitset r3("0111"); 96 | vector > m={r1, r2, r3}; 97 | bitset ma; 98 | cout< 15 | #define X real() 16 | #define Y imag() 17 | using namespace std; 18 | typedef long long ll; 19 | typedef complex co; 20 | ll ccw(co a, co b, co c) { 21 | return ((c-a)*conj(b-a)).Y; 22 | } 23 | bool up(co p, vector& h, int a, int b, int d) { 24 | int n=h.size(); 25 | return (ll)d*ccw(p, h[(a+n)%n], h[(b+n)%n])<=0; 26 | } 27 | int getTanP(co p, vector& h, int d) { 28 | int n=h.size();int mi=0;int ma=n; 29 | while (mi+1=3) return -1; 55 | } 56 | if (up(p, h, mi, mi-1, d)) mi=(mi-1+n)%n; 57 | return mi; 58 | } 59 | } 60 | pair pointHullTan(co p, vector& h) { 61 | if ((int)h.size()<=2) return {0, 0}; 62 | int t1=getTanP(p, h, -1); 63 | if (t1==-1) return {-1, -1}; 64 | return {getTanP(p, h, 1), t1}; 65 | } 66 | bool up2(vector& h1, vector& h, int a, int b, int d1, int d2) { 67 | int n=h.size();int k=getTanP(h[(b+n)%n], h1, d1); 68 | return (ll)d2*ccw(h[(a+n)%n], h[(b+n)%n], h1[k])<=0; 69 | } 70 | pair getTanH(vector& h1, vector& h, int d1, int d2) { 71 | int n=h.size();int mi=0;int ma=n; 72 | while (mi+1 > hullHullTan(vector& h1, vector& h2) { 104 | vector > ret; 105 | ret.push_back(getTanH(h1, h2, 1, 1)); 106 | ret.push_back(getTanH(h1, h2, 1, -1)); 107 | ret.push_back(getTanH(h1, h2, -1, 1)); 108 | ret.push_back(getTanH(h1, h2, -1, -1)); 109 | return ret; 110 | } -------------------------------------------------------------------------------- /src/math/simplex.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Source: https://github.com/jaehyunp/stanfordacm/blob/master/code/Simplex.cc 3 | // Two-phase simplex algorithm for solving linear programs of the form 4 | // maximize c^T x 5 | // subject to Ax <= b 6 | // x >= 0 7 | // INPUT: A -- an m x n matrix 8 | // b -- an m-dimensional vector 9 | // c -- an n-dimensional vector 10 | // x -- a vector where the optimal solution will be stored 11 | // OUTPUT: value of the optimal solution (inf if unbounded 12 | // above, -inf if infeasible) 13 | // To use this code, create an LPSolver object with A, b, and c as 14 | // arguments. Then, call Solve(x). 15 | #include 16 | using namespace std; 17 | typedef long double ld; 18 | struct LPSolver { 19 | const ld eps=1e-9; 20 | const ld inf=1e30; 21 | int m, n; 22 | vector N, B; 23 | vector > D; 24 | LPSolver(vector >& A, vector& b, vector& c) : 25 | m(b.size()), n(c.size()), N(n + 1), B(m), D(m + 2, vector(n + 2)) { 26 | for (int i = 0; i < m; i++) { 27 | for (int j = 0; j < n; j++) D[i][j] = A[i][j];} 28 | for (int i = 0; i < m; i++) { 29 | B[i] = n + i; D[i][n] = -1; D[i][n + 1] = b[i];} 30 | for (int j = 0; j < n; j++) { N[j] = j; D[m][j] = -c[j]; } 31 | N[n] = -1; D[m + 1][n] = 1; 32 | } 33 | void Pivot(int r, int s) { 34 | ld inv = 1.0 / D[r][s]; 35 | for (int i = 0; i < m + 2; i++) if (i != r) 36 | for (int j = 0; j < n + 2; j++) if (j != s) 37 | D[i][j] -= D[r][j] * D[i][s] * inv; 38 | for (int j = 0; j < n + 2; j++) if (j != s) D[r][j] *= inv; 39 | for (int i = 0; i < m + 2; i++) if (i != r) D[i][s] *= -inv; 40 | D[r][s] = inv; 41 | swap(B[r], N[s]); 42 | } 43 | bool Simplex(int phase) { 44 | int x = phase == 1 ? m + 1 : m; 45 | while (true) { 46 | int s = -1; 47 | for (int j = 0; j <= n; j++) { 48 | if (phase == 2 && N[j] == -1) continue; 49 | if (s==-1||D[x][j] -eps) return true; 52 | int r = -1; 53 | for (int i = 0; i < m; i++) { 54 | if (D[i][s] < eps) continue; 55 | if (r == -1 || D[i][n + 1] / D[i][s] < D[r][n + 1] / D[r][s] || 56 | ((D[i][n + 1]/D[i][s])==(D[r][n+1]/D[r][s])&&B[i]& x) { 63 | int r = 0; 64 | for (int i = 1; i < m; i++) if (D[i][n + 1] < D[r][n + 1]) r = i; 65 | if (D[r][n + 1] < -eps) { 66 | Pivot(r, n); 67 | if (!Simplex(1) || D[m + 1][n + 1] < -eps) return -inf; 68 | for (int i = 0; i < m; i++) if (B[i] == -1) { 69 | int s = -1; 70 | for (int j = 0; j <= n; j++) 71 | if (s==-1||D[i][j](n); 77 | for (int i = 0; i < m; i++) if (B[i] < n) x[B[i]] = D[i][n + 1]; 78 | return D[m][n + 1]; 79 | } 80 | }; 81 | int main(){ 82 | const int m = 4;const int n = 3; 83 | ld _A[m][n] = {{ 6, -1, 0 },{ -1, -5, 0 },{ 1, 5, 1 },{ -1, -5, -1 }}; 84 | ld _b[m] = { 10, -4, 5, -5 }; 85 | ld _c[n] = { 1, -1, 0 }; 86 | vector> A(m);vector b(_b, _b + m);vector c(_c, _c + n); 87 | for (int i = 0; i < m; i++) A[i] = vector(_A[i], _A[i] + n); 88 | LPSolver solver(A, b, c); 89 | vector x; 90 | ld value = solver.Solve(x); 91 | cerr << "VALUE: " << value << endl; // VALUE: 1.29032 92 | cerr << "SOLUTION:"; // SOLUTION: 1.74194 0.451613 1 93 | for (size_t i = 0; i < x.size(); i++) cerr << " " << x[i]; 94 | } -------------------------------------------------------------------------------- /src/geometry/basic.cpp: -------------------------------------------------------------------------------- 1 | // TCR 2 | // Basic geometry functions using complex numbers 3 | // Mostly copied from https://github.com/ttalvitie/libcontest/ 4 | /* Useful functions of complex number class 5 | CT abs(co x): Length 6 | CT norm(co x): Square of length 7 | CT arg(co x): Angle 8 | co polar(CT length, CT angle): Complex from polar components*/ 9 | #include 10 | #define X real() 11 | #define Y imag() 12 | using namespace std; 13 | typedef long double ld; 14 | typedef long long ll; 15 | // Coordinate type 16 | typedef ld CT; 17 | typedef complex co; 18 | ld eps=1e-12; 19 | // Return true iff points a, b, c are CCW oriented. 20 | bool ccw(co a, co b, co c) { 21 | return ((c-a)*conj(b-a)).Y>0; 22 | } 23 | // Return true iff points a, b, c are collinear. 24 | // Note: doesn't make much sense with non-integer CT. 25 | bool collinear(co a, co b, co c) { 26 | return abs(((c-a)*conj(b-a)).Y)1) return abs(p-b); 59 | return abs(z.Y)*abs(b-a); 60 | } 61 | // Return interpolation parameter between a and b of the point that is also 62 | // on line c..d. 63 | // Note: Only for non-integers! 64 | // x=a*(1-t)+b*t 65 | CT intersectionParam(co a, co b, co c, co d) { 66 | co u=(c-a)/(b-a); 67 | co v=(d-a)/(b-a); 68 | return (u.X*v.Y-u.Y*v.X)/(v.Y-u.Y); 69 | } 70 | // Intersection points of circles with centers p1 and p2 with radiuses r1 and r2 71 | // The first return value is the number of intersection points, 3 for infinite 72 | pair > circleIntersection(co p1, CT r1, co p2, CT r2) { 73 | if (norm(p1-p2)>(r1+r2)*(r1+r2)||norm(p1-p2)<(r1-r2)*(r1-r2)) 74 | return {0, {{0, 0}, {0, 0}}}; 75 | if (abs(p1-p2) lineIntersection(co a, co b, co c, co d) { 89 | if (collinear(a, b, c)&&collinear(a, b, d)) { 90 | return {2, a}; 91 | } 92 | else if(abs(((b-a)/(c-d)).Y) > segmentIntersection(co a, co b, co c, co d) { 110 | if (abs(a-b)1+eps||v<-eps||v>1+eps) { 136 | return {0, {{0, 0}, {0, 0}}}; 137 | } 138 | else { 139 | co p=a*(1-u)+b*u; 140 | return {1, {p, p}}; 141 | } 142 | } 143 | } 144 | // Returns a point from the ray bisecting the non-reflex angle abc. 145 | // Only for doubles. Returns 0 if the points are collinear. 146 | pair angleBisector(co a, co b, co c) { 147 | if (collinear(a,b,c)) return {{0, 0}, 0}; 148 | co aa=(a-b)/abs(a-b); 149 | co cc=(c-b)/abs(c-b); 150 | co bb=sqrt(aa/cc); 151 | return {b+bb*cc, 1}; 152 | } 153 | --------------------------------------------------------------------------------