├── eldiego.pdf ├── fotodiego.png ├── linuxsetup ├── math ├── func.primos ├── exp.mod.cpp ├── extended.euclid.cpp ├── simpson.cpp ├── combinatorio.cpp ├── exp.mat.cpp ├── inversos.cpp ├── frac.cpp ├── phollards.rho.villa.cpp ├── criba.cpp ├── determinante.cpp ├── fft.cpp ├── eclineales.cpp ├── phollards.rho.cpp ├── polinomio.cpp └── func.primos.cpp ├── winsetup.bat ├── eldiegorecortado.pdf ├── geometria ├── rotate.cpp ├── convex.check.cpp ├── area.cpp ├── bresenham.cpp ├── rect.cpp ├── cut.polygon.cpp ├── point.in.poly.cpp ├── convex.hull.cpp ├── line.cpp ├── orden.radial.cpp ├── point.in.convex.poly.cpp ├── segm.cpp ├── pto.cpp ├── circle.cpp └── int.circs.cpp ├── string ├── trie.cpp ├── suffix.array.short.cpp ├── zfunction.cpp ├── kmp.cpp ├── manacher.cpp ├── suffix.array.cpp ├── suffix.automaton.cpp └── corasick.cpp ├── grafos ├── union.find.cpp ├── floyd.warshall.cpp ├── bellman.ford.cpp ├── articulaciones.cpp ├── dijkstra.cpp ├── euler.cpp ├── lca.climb.cpp ├── prim.cpp ├── chuliu.villa.cpp ├── 2sat.cpp ├── kruskal.cpp ├── hungarian.villa.cpp ├── diametro.cpp ├── chuliu.cpp ├── heavylight.cpp ├── hungarian.cpp ├── biconexas.bridge.cpp ├── centroid.cpp └── dynamic.conectivity.cpp ├── Makefile ├── .gitignore ├── estructuras ├── mnum.cpp ├── rmq.static.cpp ├── disjoint.intervals.cpp ├── bitrie.cpp ├── fenwick.cpp ├── rmq.2d.cpp ├── rmq.dynamic.cpp ├── order.tree.cpp ├── rmq.lazy.cpp ├── gain-cost.set.cpp ├── rmq.mixed.cpp ├── bigint.villa.cpp ├── rmq.persistent.cpp ├── treap.hs ├── convexhull.trick.dyn.cpp ├── treap.cpp ├── bigint.cpp ├── convexhull.trick.cpp └── treaparr.cpp ├── algos ├── alphabeta.cpp ├── mosalgorithm.cpp └── lis.cpp ├── template.cpp ├── README.md ├── flow ├── edmonds.karps.cpp ├── push.relabel.villa.cpp ├── push.relabel.cpp ├── dinic.cpp ├── min.cost.max.flow.cpp └── konig.cpp ├── LICENSE ├── hash.cpp ├── algorithm.tex ├── preamble.tex ├── preamble.margenes.chicos.tex ├── villeador.py ├── eldiegorecortado.tex └── eldiego.tex /eldiego.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmartinv/eldiego/HEAD/eldiego.pdf -------------------------------------------------------------------------------- /fotodiego.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmartinv/eldiego/HEAD/fotodiego.png -------------------------------------------------------------------------------- /linuxsetup: -------------------------------------------------------------------------------- 1 | !#/bin/bash 2 | touch {a..l}.in; tee {a..l}.cpp < template.cpp 3 | -------------------------------------------------------------------------------- /math/func.primos: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmartinv/eldiego/HEAD/math/func.primos -------------------------------------------------------------------------------- /winsetup.bat: -------------------------------------------------------------------------------- 1 | FOR /L %%G IN (1,1,13) DO (copy template.cpp %%G.cpp && echo. 2>%%G.in) 2 | -------------------------------------------------------------------------------- /eldiegorecortado.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmartinv/eldiego/HEAD/eldiegorecortado.pdf -------------------------------------------------------------------------------- /math/exp.mod.cpp: -------------------------------------------------------------------------------- 1 | #define MOD 1000000007 2 | ll expmod (ll b, ll e, ll m){//O(log e) 3 | if(!e) return 1; 4 | ll q= expmod(b,e/2,m); q=(q*q)%m; 5 | return e%2? (b * q)%m : q; 6 | } 7 | -------------------------------------------------------------------------------- /geometria/rotate.cpp: -------------------------------------------------------------------------------- 1 | //rotates matrix t 90 degrees clockwise 2 | //using auxiliary matrix t2(faster) 3 | void rotate(){ 4 | forn(x, n) forn(y, n) 5 | t2[n-y-1][x]=t[x][y]; 6 | memcpy(t, t2, sizeof(t)); 7 | } 8 | -------------------------------------------------------------------------------- /math/extended.euclid.cpp: -------------------------------------------------------------------------------- 1 | void extendedEuclid (ll a, ll b){ //a * x + b * y = d 2 | if (!b) { x = 1; y = 0; d = a; return;} 3 | extendedEuclid (b, a%b); 4 | ll x1 = y; 5 | ll y1 = x - (a/b) * y; 6 | x = x1; y = y1; 7 | } 8 | -------------------------------------------------------------------------------- /math/simpson.cpp: -------------------------------------------------------------------------------- 1 | double integral(double a, double b, int n=10000) {//O(n), n=cantdiv 2 | double area=0, h=(b-a)/n, fa=f(a), fb; 3 | forn(i, n){ 4 | fb=f(a+h*(i+1)); 5 | area+=fa+ 4*f(a+h*(i+0.5)) +fb, fa=fb; 6 | } 7 | return area*h/6.;} 8 | -------------------------------------------------------------------------------- /string/trie.cpp: -------------------------------------------------------------------------------- 1 | struct trie{ 2 | map m; 3 | void add(const string &s, int p=0){ 4 | if(s[p]) m[s[p]].add(s, p+1); 5 | } 6 | void dfs(){ 7 | //Do stuff 8 | forall(it, m) 9 | it->second.dfs(); 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /geometria/convex.check.cpp: -------------------------------------------------------------------------------- 1 | bool isConvex(vector &p){//O(N), delete collinear points! 2 | int N=sz(p); 3 | if(N<3) return false; 4 | bool isLeft=p[0].left(p[1], p[2]); 5 | forr(i, 1, N) 6 | if(p[i].left(p[(i+1)%N], p[(i+2)%N])!=isLeft) 7 | return false; 8 | return true; } 9 | -------------------------------------------------------------------------------- /geometria/area.cpp: -------------------------------------------------------------------------------- 1 | double area(vector &p){//O(sz(p)) 2 | double area=0; 3 | forn(i, sz(p)) area+=p[i]^p[(i+1)%sz(p)]; 4 | //if points are in clockwise order then area is negative 5 | return abs(area)/2; 6 | } 7 | //Area ellipse = M_PI*a*b where a and b are the semi axis lengths 8 | //Area triangle = sqrt(s*(s-a)(s-b)(s-c)) where s=(a+b+c)/2 9 | -------------------------------------------------------------------------------- /grafos/union.find.cpp: -------------------------------------------------------------------------------- 1 | struct UnionFind{ 2 | vector f;//the array contains the parent of each node 3 | void init(int n){f.clear(); f.insert(f.begin(), n, -1);} 4 | int comp(int x){return (f[x]==-1?x:f[x]=comp(f[x]));}//O(1) 5 | bool join(int i, int j) { 6 | bool con=comp(i)==comp(j); 7 | if(!con) f[comp(i)] = comp(j); 8 | return con; 9 | }}; 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: eldiego.pdf 2 | 3 | AUX_EXTS:= aux|nav|snm|log|toc|vrb|dvi|idx|fdb_latexmk|fls|out|ilg|ind 4 | 5 | 6 | %.pdf: %.tex 7 | latexmk -pdf -pdflatex="pdflatex -interactive=nonstopmode" -use-make -cd $< 8 | find $(dir $<) -maxdepth 1 -regextype posix-extended -regex '.*\.(${AUX_EXTS})' -delete 9 | 10 | clean: 11 | find . -name '*.pdf' -delete 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Compiled Dynamic libraries 8 | *.so 9 | *.dylib 10 | *.dll 11 | 12 | # Compiled Static libraries 13 | *.lai 14 | *.la 15 | *.a 16 | *.lib 17 | 18 | # Executables 19 | *.exe 20 | *.out 21 | *.app 22 | 23 | # Mierda del latex 24 | *.tex.swp 25 | 26 | # basura del gummi 27 | .fuse_hidden* 28 | -------------------------------------------------------------------------------- /math/combinatorio.cpp: -------------------------------------------------------------------------------- 1 | forn(i, MAXN+1){//comb[i][k]=i tomados de a k 2 | comb[i][0]=comb[i][i]=1; 3 | forr(k, 1, i) comb[i][k]=(comb[i-1][k]+comb[i-1][k-1])%MOD; 4 | } 5 | ll lucas (ll n, ll k, int p){ //Calcula (n,k)%p teniendo comb[p][p] precalculado. 6 | ll aux = 1; 7 | while (n + k) aux = (aux * comb[n%p][k%p]) %p, n/=p, k/=p; 8 | return aux; 9 | } 10 | 11 | 12 | -------------------------------------------------------------------------------- /estructuras/mnum.cpp: -------------------------------------------------------------------------------- 1 | struct mnum{ 2 | static const tipo mod=12582917; 3 | tipo v; 4 | mnum(tipo v=0): v(v%mod) {} 5 | mnum operator+(mnum b){return v+b.v;} 6 | mnum operator-(mnum b){return v>=b.v? v-b.v : mod-b.v+v;} 7 | mnum operator*(mnum b){return v*b.v;} 8 | mnum operator^(int n){ 9 | if(!n) return 1; 10 | return n%2? (*this)^(n/2)*(this) : (*this)^(n/2);} 11 | }; 12 | -------------------------------------------------------------------------------- /geometria/bresenham.cpp: -------------------------------------------------------------------------------- 1 | //plot a line approximation in a 2d map 2 | void bresenham(pto a, pto b){ 3 | pto d=b-a; d.x=abs(d.x), d.y=abs(d.y); 4 | pto s(a.x= 0) err-=2*d.y, a.x+=s.x; 11 | if(e2 <= 0) err+= 2*d.x, a.y+= s.y; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /geometria/rect.cpp: -------------------------------------------------------------------------------- 1 | struct rect{ 2 | //lower-left and upper-right corners 3 | pto lw, up; 4 | }; 5 | //returns if there's an intersection and stores it in r 6 | bool inter(rect a, rect b, rect &r){ 7 | r.lw=pto(max(a.lw.x, b.lw.x), max(a.lw.y, b.lw.y)); 8 | r.up=pto(min(a.up.x, b.up.x), min(a.up.y, b.up.y)); 9 | //check case when only a edge is common 10 | return r.lw.x Q, vector &P){ 4 | P.clear(); 5 | forn(i, sz(Q)){ 6 | double left1=(b-a)^(Q[i]-a), left2=(b-a)^(Q[(i+1)%sz(Q)]-a); 7 | if(left1>=0) P.pb(Q[i]); 8 | if(left1*left2<0) 9 | P.pb(inter(line(Q[i], Q[(i+1)%sz(Q)]), line(a, b))); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /estructuras/rmq.static.cpp: -------------------------------------------------------------------------------- 1 | struct RMQ{ 2 | #define LVL 10 3 | tipo vec[LVL][1<<(LVL+1)]; 4 | tipo &operator[](int p){return vec[0][p];} 5 | tipo get(int i, int j) {//intervalo [i,j) 6 | int p = 31-__builtin_clz(j-i); 7 | return min(vec[p][i],vec[p][j-(1<& P) { 5 | bool c = false; 6 | forn(i, sz(P)){ 7 | int j=(i+1)%sz(P); 8 | if((P[j].y>v.y) != (P[i].y > v.y) && 9 | (v.x < (P[i].x - P[j].x) * (v.y-P[j].y) / (P[i].y - P[j].y) + P[j].x)) 10 | c = !c; 11 | } 12 | return c; 13 | } 14 | -------------------------------------------------------------------------------- /math/exp.mat.cpp: -------------------------------------------------------------------------------- 1 | #define SIZE 350 2 | int NN; 3 | double tmp[SIZE][SIZE]; 4 | void mul(double a[SIZE][SIZE], double b[SIZE][SIZE]){ zero(tmp); 5 | forn(i, NN) forn(j, NN) forn(k, NN) res[i][j]+=a[i][k]*b[k][j]; 6 | forn(i, NN) forn(j, NN) a[i][j]=res[i][j]; 7 | } 8 | void powmat(double a[SIZE][SIZE], int n, double res[SIZE][SIZE]){ 9 | forn(i, NN) forn(j, NN) res[i][j]=(i==j); 10 | while(n){ 11 | if(n&1) mul(res, a), n--; 12 | else mul(a, a), n/=2; 13 | } } 14 | -------------------------------------------------------------------------------- /grafos/floyd.warshall.cpp: -------------------------------------------------------------------------------- 1 | //G[i][j] contains weight of edge (i, j) or INF 2 | //G[i][i]=0 3 | int G[MAX_N][MAX_N]; 4 | void floyd(){//O(N^3) 5 | forn(k, N) forn(i, N) if(G[i][k]!=INF) forn(j, N) if(G[k][j]!=INF) 6 | G[i][j]=min(G[i][j], G[i][k]+G[k][j]); 7 | } 8 | bool inNegCycle(int v){ 9 | return G[v][v]<0;} 10 | //checks if there's a neg. cycle in path from a to b 11 | bool hasNegCycle(int a, int b){ 12 | forn(i, N) if(G[a][i]!=INF && G[i][i]<0 && G[i][b]!=INF) 13 | return true; 14 | return false; 15 | } 16 | -------------------------------------------------------------------------------- /grafos/bellman.ford.cpp: -------------------------------------------------------------------------------- 1 | vector G[MAX_N];//ady. list with pairs (weight, dst) 2 | int dist[MAX_N]; 3 | void bford(int src){//O(VE) 4 | dist[src]=0; 5 | forn(i, N-1) forn(j, N) if(dist[j]!=INF) forall(it, G[j]) 6 | dist[it->snd]=min(dist[it->snd], dist[j]+it->fst); 7 | } 8 | 9 | bool hasNegCycle(){ 10 | forn(j, N) if(dist[j]!=INF) forall(it, G[j]) 11 | if(dist[it->snd]>dist[j]+it->fst) return true; 12 | //inside if: all points reachable from it->snd will have -INF distance(do bfs) 13 | return false; 14 | } 15 | -------------------------------------------------------------------------------- /geometria/convex.hull.cpp: -------------------------------------------------------------------------------- 1 | //stores convex hull of P in S, CCW order 2 | //left must return >=0 to delete collinear points! 3 | void CH(vector& P, vector &S){ 4 | S.clear(); 5 | sort(P.begin(), P.end());//first x, then y 6 | forn(i, sz(P)){//lower hull 7 | while(sz(S)>= 2 && S[sz(S)-1].left(S[sz(S)-2], P[i])) S.pop_back(); 8 | S.pb(P[i]); 9 | } 10 | S.pop_back(); 11 | int k=sz(S); 12 | dforn(i, sz(P)){//upper hull 13 | while(sz(S) >= k+2 && S[sz(S)-1].left(S[sz(S)-2], P[i])) S.pop_back(); 14 | S.pb(P[i]); 15 | } 16 | S.pop_back(); 17 | } 18 | -------------------------------------------------------------------------------- /math/inversos.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | #define forr(i, a, b) for(int i=(a); i<(b); i++) 5 | typedef long long ll; 6 | 7 | #define MAXMOD 15485867 8 | ll inv[MAXMOD];//inv[i]*i=1 mod MOD 9 | void calc(int p){//O(p) 10 | inv[1]=1; 11 | forr(i, 2, p) inv[i]= p-((p/i)*inv[p%i])%p; 12 | } 13 | int inverso(int x){//O(log x) 14 | return expmod(x, eulerphi(MOD)-2);//si mod no es primo(sacar a mano) 15 | return expmod(x, MOD-2);//si mod es primo 16 | } 17 | 18 | int main(){ 19 | calc(15485867); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /grafos/articulaciones.cpp: -------------------------------------------------------------------------------- 1 | int N; 2 | vector G[1000000]; 3 | //V[i]=node number(if visited), L[i]= lowest V[i] reachable from i 4 | int qV, V[1000000], L[1000000], P[1000000]; 5 | void dfs(int v, int f){ 6 | L[v]=V[v]=++qV; 7 | forall(it, G[v]) 8 | if(!V[*it]){ 9 | dfs(*it, v); 10 | L[v] = min(L[v], L[*it]); 11 | P[v]+= L[*it]>=V[v]; 12 | } 13 | else if(*it!=f) 14 | L[v]=min(L[v], V[*it]); 15 | } 16 | int cantart(){ //O(n) 17 | qV=0; 18 | zero(V), zero(P); 19 | dfs(1, 0); P[1]--; 20 | int q=0; 21 | forn(i, N) if(P[i]) q++; 22 | return q; 23 | } 24 | -------------------------------------------------------------------------------- /algos/alphabeta.cpp: -------------------------------------------------------------------------------- 1 | ll alphabeta(State &s, bool player = true, int depth = 1e9, ll alpha = -INF, ll beta = INF) { //player = true -> Maximiza 2 | if(s.isFinal()) return s.score; 3 | //~ if (!depth) return s.heuristic(); 4 | vector children; 5 | s.expand(player, children); 6 | int n = children.size(); 7 | forn(i, n) { 8 | ll v = alphabeta(children[i], !player, depth-1, alpha, beta); 9 | if(!player) alpha = max(alpha, v); 10 | else beta = min(beta, v); 11 | if(beta <= alpha) break; 12 | } 13 | return !player ? alpha : beta;} 14 | -------------------------------------------------------------------------------- /estructuras/disjoint.intervals.cpp: -------------------------------------------------------------------------------- 1 | bool operator< (const ii &a, const ii &b) {return a.fst segs; 6 | void insert(ii v) {//O(lgn) 7 | if(v.snd-v.fst==0.) return;//OJO 8 | set::iterator it,at; 9 | at = it = segs.lower_bound(v); 10 | if (at!=segs.begin() && (--at)->snd >= v.fst) 11 | v.fst = at->fst, --it; 12 | for(; it!=segs.end() && it->fst <= v.snd; segs.erase(it++)) 13 | v.snd=max(v.snd, it->snd); 14 | segs.insert(v); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /estructuras/bitrie.cpp: -------------------------------------------------------------------------------- 1 | struct bitrie{ 2 | static const int sz=1<<5;//5=ceil(log(n)) 3 | int V;//valor del nodo 4 | vector ch;//childs 5 | bitrie():V(0){}//NEUTRO 6 | void set(int p, int v, int bit=sz>>1){//O(log sz) 7 | if(bit){ 8 | ch.resize(2); 9 | ch[(p&bit)>0].set(p, v, bit>>1); 10 | V=max(ch[0].V, ch[1].V); 11 | } 12 | else V=v; 13 | } 14 | int get(int i, int j, int a=0, int b=sz){//O(log sz) 15 | if(j<=a || i>=b) return 0;//NEUTRO 16 | if(i<=a && b<=j) return V; 17 | if(!sz(ch)) return V; 18 | int c=(a+b)/2; 19 | return max(ch[0].get(i, j, a, c), ch[1].get(i, j, c, b)); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /geometria/line.cpp: -------------------------------------------------------------------------------- 1 | int sgn(ll x){return x<0? -1 : !!x;} 2 | struct line{ 3 | line() {} 4 | double a,b,c;//Ax+By=C 5 | //pto MUST store float coordinates! 6 | line(double a, double b, double c):a(a),b(b),c(c){} 7 | line(pto p, pto q): a(q.y-p.y), b(p.x-q.x), c(a*p.x+b*p.y) {} 8 | int side(pto p){return sgn(ll(a) * p.x + ll(b) * p.y - c);} 9 | }; 10 | bool parallels(line l1, line l2){return abs(l1.a*l2.b-l2.a*l1.b) 0 && a.y >= 0)return 0; 6 | if(a.x <= 0 && a.y > 0)return 1; 7 | if(a.x < 0 && a.y <= 0)return 2; 8 | if(a.x >= 0 && a.y < 0)return 3; 9 | assert(a.x ==0 && a.y==0); 10 | return -1; 11 | } 12 | bool cmp(const pto&p1, const pto&p2)const{ 13 | int c1 = cuad(p1), c2 = cuad(p2); 14 | if(c1==c2) return p1.y*p2.x &pt){//delete collinear points first! 2 | //this makes it clockwise: 3 | if(pt[2].left(pt[0], pt[1])) reverse(pt.begin(), pt.end()); 4 | int n=sz(pt), pi=0; 5 | forn(i, n) 6 | if(pt[i].x shift(n);//puts pi as first point 9 | forn(i, n) shift[i]=pt[(pi+i)%n]; 10 | pt.swap(shift); 11 | } 12 | bool inPolygon(pto p, const vector &pt){ 13 | //call normalize first! 14 | if(p.left(pt[0], pt[1]) || p.left(pt[sz(pt)-1], pt[0])) return false; 15 | int a=1, b=sz(pt)-1; 16 | while(b-a>1){ 17 | int c=(a+b)/2; 18 | if(!p.left(pt[0], pt[c])) a=c; 19 | else b=c; 20 | } 21 | return !p.left(pt[a], pt[a+1]); 22 | } 23 | -------------------------------------------------------------------------------- /algos/mosalgorithm.cpp: -------------------------------------------------------------------------------- 1 | int n,sq; 2 | struct Qu{//queries [l, r] 3 | //intervalos cerrado abiertos !!! importante!! 4 | int l, r, id; 5 | }qs[MAXN]; 6 | int ans[MAXN], curans;//ans[i]=ans to ith query 7 | bool bymos(const Qu &a, const Qu &b){ 8 | if(a.l/sq!=b.l/sq) return a.lb.r; 10 | } 11 | void mos(){ 12 | forn(i, t) qs[i].id=i; 13 | sort(qs, qs+t, bymos); 14 | int cl=0, cr=0; 15 | sq=sqrt(n); 16 | curans=0; 17 | forn(i, t){ //intervalos cerrado abiertos !!! importante!! 18 | Qu &q=qs[i]; 19 | while(cl>q.l) add(--cl); 20 | while(crq.r) remove(--cr); 23 | ans[q.id]=curans; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /template.cpp: -------------------------------------------------------------------------------- 1 | //touch {a..m}.in; tee {a..m}.cpp < template.cpp 2 | #include 3 | using namespace std; 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define sz(c) ((int)c.size()) 7 | #define zero(v) memset(v, 0, sizeof(v)) 8 | #define forall(it,v) for(auto it=v.begin();it!=v.end();++it) 9 | #define pb push_back 10 | #define fst first 11 | #define snd second 12 | typedef long long ll; 13 | typedef pair ii; 14 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 15 | #define dprint(v) cout << #v"=" << v << endl //;) 16 | 17 | const int MAXN=100100; 18 | int n; 19 | 20 | int main() { 21 | freopen("input.in", "r", stdin); 22 | ios::sync_with_stdio(0); 23 | while(cin >> n){ 24 | 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /grafos/dijkstra.cpp: -------------------------------------------------------------------------------- 1 | #define INF 1e9 2 | int N; 3 | #define MAX_V 250001 4 | vector G[MAX_V]; 5 | //To add an edge use 6 | #define add(a, b, w) G[a].pb(make_pair(w, b)) 7 | ll dijkstra(int s, int t){//O(|E| log |V|) 8 | priority_queue, greater > Q; 9 | vector dist(N, INF); vector dad(N, -1); 10 | Q.push(make_pair(0, s)); dist[s] = 0; 11 | while(sz(Q)){ 12 | ii p = Q.top(); Q.pop(); 13 | if(p.snd == t) break; 14 | forall(it, G[p.snd]) 15 | if(dist[p.snd]+it->first < dist[it->snd]){ 16 | dist[it->snd] = dist[p.snd] + it->fst; 17 | dad[it->snd] = p.snd; 18 | Q.push(make_pair(dist[it->snd], it->snd)); } 19 | } 20 | return dist[t]; 21 | if(dist[t] curl -O https://labdcc.fceia.unr.edu.ar/~mvillagra/geany.colors.tar.gz && tar -zxf geany.colors.tar.gz -C ~/.config/geany/colorschemes/ 12 | 13 | 2) In Geany: 14 | View -> Change Color scheme... 15 | 16 | Villeador de C++ 17 | ----------- 18 | A small utility to remove all possible spaces from C++ code. Taken from: 19 | https://github.com/Scylardor/cminify 20 | -------------------------------------------------------------------------------- /estructuras/fenwick.cpp: -------------------------------------------------------------------------------- 1 | //For 2D threat each column as a Fenwick tree, by adding a nested for in each operation 2 | struct Fenwick{ 3 | static const int sz=1000001; 4 | tipo t[sz]; 5 | void adjust(int p, tipo v){//valid with p in [1, sz), O(lgn) 6 | for(int i=p; i= tree[t]) 20 | idx = t, x -= tree[t]; 21 | mask >>= 1; 22 | } 23 | return idx; 24 | }}; 25 | -------------------------------------------------------------------------------- /math/frac.cpp: -------------------------------------------------------------------------------- 1 | tipo mcd(tipo a, tipo b){return a?mcd(b%a, a):b;} 2 | struct frac{ 3 | tipo p,q; 4 | frac(tipo p=0, tipo q=1):p(p),q(q) {norm();} 5 | void norm(){ 6 | tipo a = mcd(p,q); 7 | if(a) p/=a, q/=a; 8 | else q=1; 9 | if (q<0) q=-q, p=-p;} 10 | frac operator+(const frac& o){ 11 | tipo a = mcd(q,o.q); 12 | return frac(p*(o.q/a)+o.p*(q/a), q*(o.q/a));} 13 | frac operator-(const frac& o){ 14 | tipo a = mcd(q,o.q); 15 | return frac(p*(o.q/a)-o.p*(q/a), q*(o.q/a));} 16 | frac operator*(frac o){ 17 | tipo a = mcd(q,o.p), b = mcd(o.q,p); 18 | return frac((p/b)*(o.p/a), (q/a)*(o.q/b));} 19 | frac operator/(frac o){ 20 | tipo a = mcd(q,o.q), b = mcd(o.p,p); 21 | return frac((p/b)*(o.q/a),(q/a)*(o.p/b));} 22 | bool operator<(const frac &o) const{return p*o.q < o.p*q;} 23 | bool operator==(frac o){return p==o.p&&q==o.q;} 24 | }; 25 | -------------------------------------------------------------------------------- /geometria/segm.cpp: -------------------------------------------------------------------------------- 1 | struct segm{ 2 | pto s,f; 3 | segm(pto s, pto f):s(s), f(f) {} 4 | pto closest(pto p) {//use for dist to point 5 | double l2 = dist_sq(s, f); 6 | if(l2==0.) return s; 7 | double t =((p-s)*(f-s))/l2; 8 | if (t<0.) return s;//not write if is a line 9 | else if(t>1.)return f;//not write if is a line 10 | return s+((f-s)*t); 11 | } 12 | bool inside(pto p){return abs(dist(s, p)+dist(p, f)-dist(s, f)) G[MAX_V];//limpiar esto 7 | //To add an edge use 8 | #define add(a, b, w) G[a][b]=w 9 | int f, p[MAX_V]; 10 | void augment(int v, int minE){ 11 | if(v==SRC) f=minE; 12 | else if(p[v]!=-1){ 13 | augment(p[v], min(minE, G[p[v]][v])); 14 | G[p[v]][v]-=f, G[v][p[v]]+=f; 15 | } 16 | } 17 | ll maxflow(){//O(VE^2) 18 | ll Mf=0; 19 | do{ 20 | f=0; 21 | char used[MAX_V]; queue q; q.push(SRC); 22 | zero(used), memset(p, -1, sizeof(p)); 23 | while(sz(q)){ 24 | int u=q.front(); q.pop(); 25 | if(u==SNK) break; 26 | forall(it, G[u]) 27 | if(it->snd>0 && !used[it->fst]) 28 | used[it->fst]=true, q.push(it->fst), p[it->fst]=u; 29 | } 30 | augment(SNK, INF); 31 | Mf+=f; 32 | }while(f); 33 | return Mf; 34 | } 35 | -------------------------------------------------------------------------------- /math/phollards.rho.villa.cpp: -------------------------------------------------------------------------------- 1 | ll mulmod(ll a,ll b,ll c){ll x=0,y=a%c;while(b>0){if(b%2==1)x=(x+y)%c;y=(y*2)%c;b/=2;}return x%c;}ll expmod(ll b,ll e,ll m){if(!e)return 1;ll q=expmod(b,e/2,m);q=mulmod(q,q,m);return e%2?mulmod(b,q,m):q;}bool es_primo_prob(ll n,int a){if(n==a)return true;ll s=0,d=n-1;while(d%2==0)s++,d/=2;ll x=expmod(a,d,n);if((x==1)||(x+1==n))return true;forn(i,s-1){x=mulmod(x,x,n);if(x==1)return false;if(x+1==n)return true;}return false;}bool rabin(ll n){if(n==1)return false;const int ar[]={2,3,5,7,11,13,17,19,23};forn(j,9)if(!es_primo_prob(n,ar[j]))return false;return true;}ll rho(ll n){if((n&1)==0)return 2;ll x=2,y=2,d=1;ll c=rand()%n+1;while(d==1){x=(mulmod(x,x,n)+c)%n;y=(mulmod(y,y,n)+c)%n;y=(mulmod(y,y,n)+c)%n;if(x-y>=0)d=gcd(x-y,n);else d=gcd(y-x,n);}return d==n?rho(n):d;}mapprim;void factRho(ll n){if(n==1)return;if(rabin(n)){prim[n]++;return;}ll factor=rho(n);factRho(factor);factRho(n/factor);} 2 | -------------------------------------------------------------------------------- /grafos/euler.cpp: -------------------------------------------------------------------------------- 1 | int n,m,ars[MAXE], eq; 2 | vector G[MAXN];//fill G,n,m,ars,eq 3 | list path; 4 | int used[MAXN]; 5 | bool usede[MAXE]; 6 | queue::iterator> q; 7 | int get(int v){ 8 | while(used[v]::iterator it){ 12 | int ar=G[v][get(v)]; int u=v^ars[ar]; 13 | usede[ar]=true; 14 | list::iterator it2=path.insert(it, u); 15 | if(u!=r) explore(u, r, it2); 16 | if(get(v)::iterator>(); 22 | path.push_back(0); q.push(path.begin()); 23 | while(sz(q)){ 24 | list::iterator it=q.front(); q.pop(); 25 | if(used[*it]0;){ 10 | t[i].set(j, val); 11 | i/=2; 12 | val=operacion(t[i*2][j], t[i*2+1][j]); 13 | } } 14 | tipo get(int i1, int j1, int i2, int j2){return get(i1,j1,i2,j2,1,0,sz);} 15 | //O(lgm.lgn), rangos cerrado abierto 16 | int get(int i1, int j1, int i2, int j2, int n, int a, int b){ 17 | if(i2<=a || i1>=b) return 0; 18 | if(i1<=a && b<=i2) return t[n].get(j1, j2); 19 | int c=(a+b)/2; 20 | return operacion(get(i1, j1, i2, j2, 2*n, a, c), 21 | get(i1, j1, i2, j2, 2*n+1, c, b)); 22 | } 23 | } rmq; 24 | //Example to initialize a grid of M rows and N columns: 25 | RMQ2D rmq; rmq.init(n,m); 26 | forn(i, n) forn(j, m){ 27 | int v; cin >> v; rmq.set(i, j, v);} 28 | -------------------------------------------------------------------------------- /estructuras/rmq.dynamic.cpp: -------------------------------------------------------------------------------- 1 | //Dado un arreglo y una operacion asociativa con neutro, get(i, j) opera sobre el rango [i, j). 2 | #define MAXN 100000 3 | #define operacion(x, y) max(x, y) 4 | const int neutro=0; 5 | struct RMQ{ 6 | int sz; 7 | tipo t[4*MAXN]; 8 | tipo &operator[](int p){return t[sz+p];} 9 | void init(int n){//O(nlgn) 10 | sz = 1 << (32-__builtin_clz(n)); 11 | forn(i, 2*sz) t[i]=neutro; 12 | } 13 | void updall(){//O(n) 14 | dforn(i, sz) t[i]=operacion(t[2*i], t[2*i+1]);} 15 | tipo get(int i, int j){return get(i,j,1,0,sz);} 16 | tipo get(int i, int j, int n, int a, int b){//O(lgn) 17 | if(j<=a || i>=b) return neutro; 18 | if(i<=a && b<=j) return t[n]; 19 | int c=(a+b)/2; 20 | return operacion(get(i, j, 2*n, a, c), get(i, j, 2*n+1, c, b)); 21 | } 22 | void set(int p, tipo val){//O(lgn) 23 | for(p+=sz; p>0 && t[p]!=val;){ 24 | t[p]=val; 25 | p/=2; 26 | val=operacion(t[p*2], t[p*2+1]); 27 | } 28 | } 29 | }rmq; 30 | //Usage: 31 | cin >> n; rmq.init(n); forn(i, n) cin >> rmq[i]; rmq.updall(); 32 | -------------------------------------------------------------------------------- /string/suffix.array.short.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define forn(i, n) for(int i=0; i<(n); i++) 8 | #define forr(i, a, b) for(int i=a; i<(b); i++) 9 | const int MAXN = 100100; 10 | 11 | 12 | pair sf[MAXN]; 13 | bool comp(int lhs, int rhs) {return sf[lhs] < sf[rhs];} 14 | struct SuffixArray { 15 | //sa guarda los indices de los sufijos ordenados 16 | int sa[MAXN], r[MAXN]; 17 | void init(const char *a, int n) { 18 | forn(i, n) r[i] = a[i]; 19 | for(int m = 1; m < n; m <<= 1) { 20 | forn(i, n) sa[i]=i, sf[i] = make_pair(r[i], i+m> in){ 31 | sa.init(in, strlen(in)); 32 | forn(i, (int)strlen(in)) cout << '\t' << in+sa.sa[i] << '\n'; 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /estructuras/order.tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | #define dprint(v) cerr << #v"=" << v << endl //;) 5 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 6 | #define forn(i,n) forr(i,0,n) 7 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 8 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 9 | #define sz(c) ((int)c.size()) 10 | #define zero(v) memset(v, 0, sizeof(v)) 11 | #define pb push_back 12 | #define fst first 13 | #define snd second 14 | typedef long long ll; 15 | typedef pair ii; 16 | 17 | #include 18 | #include 19 | using namespace __gnu_pbds; 20 | typedef tree,//key,mapped type, comparator 21 | rb_tree_tag,tree_order_statistics_node_update> set_t; 22 | //find_by_order(i) devuelve iterador al i-esimo elemento 23 | //order_of_key(k): devuelve la pos del lower bound de k 24 | //Ej: 12, 100, 505, 1000, 10000. 25 | //order_of_key(10) == 0, order_of_key(100) == 1, 26 | //order_of_key(707) == 3, order_of_key(9999999) == 5 27 | 28 | int main() 29 | { 30 | 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Mariano Crosetti, Martín Villagra, Pablo Zimmermann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /grafos/prim.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | #define dprint(v) cerr << #v"=" << v << endl //;) 11 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 12 | #define forn(i,n) forr(i,0,n) 13 | #define dforsn(i,a,b) for(int i=(b)-1; i>=a; i--) 14 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 15 | #define sz(c) ((int)c.size()) 16 | #define zero(v) memset(v, 0, sizeof(v)) 17 | typedef long long ll; 18 | typedef pair ii; 19 | const int MAXN=100000; 20 | 21 | int n; 22 | vector G[MAXN]; 23 | bool taken[MAXN]; 24 | priority_queue, greater > pq;//min heap 25 | void process(int v){ 26 | taken[v]=true; 27 | forall(e, G[v]) 28 | if(!taken[e->second]) pq.push(*e); 29 | } 30 | 31 | ll prim(){ 32 | zero(taken); 33 | process(0); 34 | ll cost=0; 35 | while(sz(pq)){ 36 | ii e=pq.top(); pq.pop(); 37 | if(!taken[e.second]) cost+=e.first, process(e.second); 38 | } 39 | return cost; 40 | } 41 | 42 | int main(){ 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /string/zfunction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cerr << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(auto it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | typedef long long ll; 14 | typedef pair ii; 15 | 16 | const int MAXN=100100; 17 | char s[MAXN]; 18 | int z[MAXN]; // z[i] = i==0 ? 0 : max k tq s[0,k) match with s[i,i+k) 19 | void z_function(char s[],int z[]) { 20 | int n = strlen(s); 21 | forn(i, n) z[i]=0; 22 | for (int i = 1, l = 0, r = 0; i < n; ++i) { 23 | if (i <= r) z[i] = min (r - i + 1, z[i - l]); 24 | while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i]; 25 | if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1; 26 | } 27 | } 28 | 29 | int main() { 30 | ios::sync_with_stdio(0); 31 | while(cin >> s){ int slen = strlen(s); 32 | z_function(s,z); 33 | forn(i,slen) cout << z[i] << ' '; 34 | cout << endl; 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /hash.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cerr << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | typedef long long ll; 14 | typedef pair ii; 15 | 16 | //Compilar: g++ --std=c++11 17 | struct Hash{ 18 | size_t operator()(const ii &a)const{ 19 | size_t s=hash()(a.fst); 20 | return hash()(a.snd)+0x9e3779b9+(s<<6)+(s>>2); 21 | } 22 | size_t operator()(const vector &v)const{ 23 | size_t s=0; 24 | for(auto &e : v) 25 | s ^= hash()(e)+0x9e3779b9+(s<<6)+(s>>2); 26 | return s; 27 | } 28 | }; 29 | unordered_set s; 30 | unordered_map m;//map 31 | 32 | int main() { 33 | srand(time(NULL)); 34 | set coli; 35 | forn(i, 1000000){ 36 | s.insert(ii(rand()%10000, rand()%10000)); 37 | coli.insert(Hash()(ii(rand()%10000, rand()%10000))); 38 | } 39 | dprint(sz(coli)); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /flow/push.relabel.villa.cpp: -------------------------------------------------------------------------------- 1 | #define MAX_V 1000 2 | int N;//valid nodes are [0...N-1] 3 | #define INF 1e9 4 | //special nodes 5 | #define SRC 0 6 | #define SNK 1 7 | map G[MAX_V]; 8 | //To add an edge use 9 | #define add(a, b, w) G[a][b]=w 10 | ll excess[MAX_V]; 11 | int height[MAX_V], active[MAX_V], count[2*MAX_V+1]; 12 | queue Q;void enqueue(int v) { if (!active[v] && excess[v] > 0) active[v]=true, Q.push(v); } 13 | void push(int a,int b){int amt=min(excess[a],ll(G[a][b]));if(height[a]<=height[b]||amt==0)return;G[a][b]-=amt,G[b][a]+=amt;excess[b]+=amt,excess[a]-=amt;enqueue(b);} 14 | void gap(int k){forn(v,N){if(height[v]snd)height[v]=min(height[v],height[it->fst]+1);count[height[v]]++;enqueue(v);} 16 | ll maxflow(){zero(height),zero(active),zero(count),zero(excess);count[0]=N-1;count[N]=1;height[SRC]=N;active[SRC]=active[SNK]=true;forall(it,G[SRC]){excess[SRC]+=it->snd;push(SRC,it->fst);}while(sz(Q)){int v=Q.front();Q.pop();active[v]=false;forall(it,G[v])push(v,it->fst);if(excess[v]>0)count[height[v]]==1?gap(height[v]):relabel(v);}ll mf=0;forall(it,G[SRC])mf+=G[it->fst][SRC];return mf;} 17 | -------------------------------------------------------------------------------- /grafos/chuliu.villa.cpp: -------------------------------------------------------------------------------- 1 | void visit(graph&h,int v,int s,int r,vector&no,vector>&comp,vector&prev,vector>&next,vector&mcost,vector&mark,weight&cost,bool&found){if(mark[v]){vectortemp=no;found=true;do{cost+=mcost[v];v=prev[v];if(v!=s){while(comp[v].size()>0){no[comp[v].back()]=s;comp[s].push_back(comp[v].back());comp[v].pop_back();}}}while(v!=s);forall(j,comp[s])if(*j!=r)forall(e,h[*j])if(no[e->src]!=s)e->w-=mcost[ temp[*j] ];}mark[v]=true;forall(i,next[v])if(no[*i]!=no[v]&&prev[no[*i]]==v)if(!mark[no[*i]]||*i==s)visit(h,*i,s,r,no,comp,prev,next,mcost,mark,cost,found);}weight minimumSpanningArborescence(const graph&g,int r){const int n=sz(g);graph h(n);forn(u,n)forall(e,g[u])h[e->dst].pb(*e);vectorno(n);vector>comp(n);forn(u,n)comp[u].pb(no[u]=u);for(weight cost=0;;){vectorprev(n,-1);vectormcost(n,INF);forn(j,n)if(j!=r)forall(e,h[j])if(no[e->src]!=no[j])if(e->ww,prev[ no[j] ]=no[e->src];vector>next(n);forn(u,n)if(prev[u]>=0)next[ prev[u] ].push_back(u);bool stop=true;vectormark(n);forn(u,n)if(u!=r&&!mark[u]&&!comp[u].empty()){bool found=false;visit(h,u,u,r,no,comp,prev,next,mcost,mark,cost,found);if(found)stop=false;}if(stop){forn(u,n)if(prev[u]>=0)cost+=mcost[u];return cost;}}} 2 | -------------------------------------------------------------------------------- /grafos/2sat.cpp: -------------------------------------------------------------------------------- 1 | //We have a vertex representing a var and other for his negation. 2 | //Every edge stored in G represents an implication. To add an equation of the form a||b, use addor(a, b) 3 | //MAX=max cant var, n=cant var 4 | #define addor(a, b) (G[neg(a)].pb(b), G[neg(b)].pb(a)) 5 | vector G[MAX*2]; 6 | //idx[i]=index assigned in the dfs 7 | //lw[i]=lowest index(closer from the root) reachable from i 8 | int lw[MAX*2], idx[MAX*2], qidx; 9 | stack q; 10 | int qcmp, cmp[MAX*2]; 11 | //verdad[cmp[i]]=valor de la variable i 12 | bool verdad[MAX*2+1]; 13 | 14 | int neg(int x) { return x>=n? x-n : x+n;} 15 | void tjn(int v){ 16 | lw[v]=idx[v]=++qidx; 17 | q.push(v), cmp[v]=-2; 18 | forall(it, G[v]){ 19 | if(!idx[*it] || cmp[*it]==-2){ 20 | if(!idx[*it]) tjn(*it); 21 | lw[v]=min(lw[v], lw[*it]); 22 | } 23 | } 24 | if(lw[v]==idx[v]){ 25 | int x; 26 | do{x=q.top(); q.pop(); cmp[x]=qcmp;}while(x!=v); 27 | verdad[qcmp]=(cmp[neg(v)]<0); 28 | qcmp++; 29 | } 30 | } 31 | //remember to CLEAR G!!! 32 | bool satisf(){//O(n) 33 | memset(idx, 0, sizeof(idx)), qidx=0; 34 | memset(cmp, -1, sizeof(cmp)), qcmp=0; 35 | forn(i, n){ 36 | if(!idx[i]) tjn(i); 37 | if(!idx[neg(i)]) tjn(neg(i)); 38 | } 39 | forn(i, n) if(cmp[i]==cmp[neg(i)]) return false; 40 | return true; 41 | } 42 | -------------------------------------------------------------------------------- /grafos/kruskal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | #define dprint(v) cerr << #v"=" << v << endl //;) 10 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 11 | #define forn(i,n) forr(i,0,n) 12 | #define dforsn(i,a,b) for(int i=(b)-1; i>=a; i--) 13 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 14 | #define sz(c) ((int)c.size()) 15 | #define zero(v) memset(v, 0, sizeof(v)) 16 | typedef long long ll; 17 | typedef pair ii; 18 | const int MAXN=100000; 19 | struct UF{ 20 | void init(int n){} 21 | void unir(int a, int v){} 22 | int comp(int n){return 0;} 23 | }uf; 24 | vector G[MAXN]; 25 | int n; 26 | 27 | struct Ar{int a,b,w;}; 28 | bool operator<(const Ar& a, const Ar &b){return a.w E; 30 | ll kruskal(){ 31 | ll cost=0; 32 | sort(E.begin(), E.end());//ordenar aristas de menor a mayor 33 | uf.init(n); 34 | forall(it, E){ 35 | if(uf.comp(it->a)!=uf.comp(it->b)){//si no estan conectados 36 | uf.unir(it->a, it->b);//conectar 37 | cost+=it->w; 38 | } 39 | } 40 | return cost; 41 | } 42 | 43 | int main(){ 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /geometria/pto.cpp: -------------------------------------------------------------------------------- 1 | const double EPS=1e-9; 2 | struct pto{ 3 | double x, y; 4 | pto(double x=0, double y=0):x(x),y(y){} 5 | pto operator+(pto a){return pto(x+a.x, y+a.y);} 6 | pto operator-(pto a){return pto(x-a.x, y-a.y);} 7 | pto operator+(double a){return pto(x+a, y+a);} 8 | pto operator*(double a){return pto(x*a, y*a);} 9 | pto operator/(double a){return pto(x/a, y/a);} 10 | //dot product, producto interno: 11 | double operator*(pto a){return x*a.x+y*a.y;} 12 | //module of the cross product or vectorial product: 13 | //if a is less than 180 clockwise from b, a^b>0 14 | double operator^(pto a){return x*a.y-y*a.x;} 15 | //returns true if this is at the left side of line qr 16 | bool left(pto q, pto r){return ((q-*this)^(r-*this))>0;} 17 | bool operator<(const pto &a) const{return x 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | #define dprint(v) cerr << #v"=" << v << endl //;) 11 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 12 | #define forn(i,n) forr(i,0,n) 13 | #define dforsn(i,a,b) for(int i=(b)-1; i>=a; i--) 14 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 15 | #define sz(c) ((int)c.size()) 16 | #define zero(v) memset(v, 0, sizeof(v)) 17 | typedef long long ll; 18 | typedef pair ii; 19 | const int MAXLEN=100000; 20 | 21 | string T;//cadena donde buscar(where) 22 | string P;//cadena a buscar(what) 23 | int b[MAXLEN];//back table b[i] maximo borde de [0..i) 24 | void kmppre(){//by gabina with love 25 | int i =0, j=-1; b[0]=-1; 26 | while(i=0 && P[i] != P[j]) j=b[j]; 28 | i++, j++, b[i] = j; 29 | } 30 | } 31 | void kmp(){ 32 | int i=0, j=0; 33 | while(i=0 && T[i]!=P[j]) j=b[j]; 35 | i++, j++; 36 | if(j==sz(P)) printf("P is found at index %d in T\n", i-j), j=b[j]; 37 | } 38 | } 39 | 40 | int main(){ 41 | cout << "T="; 42 | cin >> T; 43 | cout << "P="; 44 | cin.ignore(); 45 | cin >> P; 46 | kmppre(); 47 | kmp(); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /string/manacher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define dforn(i, n) for(int i=(n)-1; i>=0; i--) 8 | #define forr(i, a, b) for(int i=(a); i<(b); i++) 9 | #define forn(i, n) forr(i, 0, n) 10 | #define sz(v) ((int)v.size()) 11 | #define zero(v) memset(v, 0, sizeof(v)); 12 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 13 | #define INF 1e9 14 | typedef pair ii; 15 | const int MAXN=100100; 16 | 17 | string s; 18 | int d1[MAXN];//d1[i]=long del maximo palindromo impar con centro en i 19 | int d2[MAXN];//d2[i]=analogo pero para longitud par 20 | //0 1 2 3 4 21 | //a a b c c <--d1[2]=3 22 | //a a b b <--d2[2]=2 (estan uno antes) 23 | void manacher(){ 24 | int l=0, r=-1, n=sz(s); 25 | forn(i, n){ 26 | int k=(i>r? 1 : min(d1[l+r-i], r-i)); 27 | while(i+k=0 && s[i+k]==s[i-k]) ++k; 28 | d1[i] = k--; 29 | if(i+k > r) l=i-k, r=i+k; 30 | } 31 | l=0, r=-1; 32 | forn(i, n){ 33 | int k=(i>r? 0 : min(d2[l+r-i+1], r-i+1))+1; 34 | while(i+k-1=0 && s[i+k-1]==s[i-k]) k++; 35 | d2[i] = --k; 36 | if(i+k-1 > r) l=i-k, r=i+k-1; 37 | } 38 | } 39 | 40 | int main(){ 41 | while(cin >> s){ 42 | manacher(); 43 | forn(i, sz(s)) cout << d1[i] << ' '; cout << endl; 44 | forn(i, sz(s)) cout << d2[i] << ' '; cout << endl; 45 | } 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /math/criba.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | #define dprint(v) cerr << #v"=" << v << endl //;) 11 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 12 | #define forn(i,n) forr(i,0,n) 13 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 14 | #define sz(c) ((int)c.size()) 15 | #define zero(v) memset(v, 0, sizeof(v)) 16 | typedef long long ll; 17 | typedef pair ii; 18 | 19 | #define MAXP 100000 //no necesariamente primo 20 | int criba[MAXP+1]; 21 | void crearcriba(){ 22 | int w[] = {4,2,4,2,4,6,2,6}; 23 | for(int p=25;p<=MAXP;p+=10) criba[p]=5; 24 | for(int p=9;p<=MAXP;p+=6) criba[p]=3; 25 | for(int p=4;p<=MAXP;p+=2) criba[p]=2; 26 | for(int p=7,cur=0;p*p<=MAXP;p+=w[cur++&7]) if (!criba[p]) 27 | for(int j=p*p;j<=MAXP;j+=(p<<1)) if(!criba[j]) criba[j]=p; 28 | } 29 | vector primos; 30 | void buscarprimos(){ 31 | crearcriba(); 32 | forr (i,2,MAXP+1) if (!criba[i]) primos.push_back(i); 33 | } 34 | //~ Useful for bit trick: #define SET(i) ( criba[(i)>>5]|=1<<((i)&31) ), #define INDEX(i) ( (criba[i>>5]>>((i)&31))&1 ), unsigned int criba[MAXP/32+1]; 35 | 36 | 37 | int main() { 38 | freopen("primos", "w", stdout); 39 | buscarprimos(); 40 | cout << '{'; 41 | bool first=true; 42 | forall(it, primos){ 43 | if(first) first=false; 44 | else cout << ','; 45 | cout << *it; 46 | } 47 | cout << "};\n"; 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /grafos/hungarian.villa.cpp: -------------------------------------------------------------------------------- 1 | //Dado un grafo bipartito completo con costos no negativos, encuentra el matching perfecto de minimo costo. 2 | const tipo EPS=1e-9;const tipo INF=1e14; 3 | #define N 502 4 | tipo cost[N][N],lx[N],ly[N],slack[N];int n,max_match,xy[N],yx[N],slackx[N],prev2[N];bool S[N],T[N];void add_to_tree(int x,int prevx){S[x]=true,prev2[x]=prevx;forn(y,n)if(lx[x]+ly[y]-cost[x][y] 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | #define dforn(i, n) for(int i=(n)-1; i>=0; i--) 7 | #define forr(i, a, b) for(int i=(a); i<(b); i++) 8 | #define forn(i, n) forr(i, 0, n) 9 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 10 | #define INF 1e9 11 | typedef pair ii; 12 | const int MAXN=100100; 13 | 14 | //Para non-increasing, cambiar comparaciones y revisar busq binaria 15 | //Given an array, paint it in the least number of colors so that each color turns to a non-increasing subsequence. 16 | //Solution:Min number of colors=Length of the longest increasing subsequence 17 | int N, a[MAXN];//secuencia y su longitud 18 | ii d[MAXN+1];//d[i]=ultimo valor de la subsecuencia de tamanio i 19 | int p[MAXN];//padres 20 | vector R;//respuesta 21 | void rec(int i){ 22 | if(i==-1) return; 23 | R.push_back(a[i]); 24 | rec(p[i]); 25 | } 26 | int lis(){//O(nlogn) 27 | d[0] = ii(-INF, -1); forn(i, N) d[i+1]=ii(INF, -1); 28 | forn(i, N){ 29 | int j = upper_bound(d, d+N+1, ii(a[i], INF))-d; 30 | if (d[j-1].first < a[i]&&a[i] < d[j].first){ 31 | p[i]=d[j-1].second; 32 | d[j] = ii(a[i], i); 33 | } 34 | } 35 | R.clear(); 36 | dforn(i, N+1) if(d[i].first!=INF){ 37 | rec(d[i].second);//reconstruir 38 | reverse(R.begin(), R.end()); 39 | return i;//longitud 40 | } 41 | return 0; 42 | } 43 | 44 | int main(){ 45 | while(cin >> N){ 46 | forn(i, N) cin >> a[i]; 47 | lis(); 48 | forall(it, R) cout << *it << ' '; cout << endl; 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /flow/push.relabel.cpp: -------------------------------------------------------------------------------- 1 | #define MAX_V 1000 2 | int N;//valid nodes are [0...N-1] 3 | #define INF 1e9 4 | //special nodes 5 | #define SRC 0 6 | #define SNK 1 7 | map G[MAX_V]; 8 | //To add an edge use 9 | #define add(a, b, w) G[a][b]=w 10 | ll excess[MAX_V]; 11 | int height[MAX_V], active[MAX_V], count[2*MAX_V+1]; 12 | queue Q; 13 | void enqueue(int v) { 14 | if (!active[v] && excess[v] > 0) active[v]=true, Q.push(v); } 15 | void push(int a, int b) { 16 | int amt = min(excess[a], ll(G[a][b])); 17 | if(height[a] <= height[b] || amt == 0) return; 18 | G[a][b]-=amt, G[b][a]+=amt; 19 | excess[b] += amt, excess[a] -= amt; 20 | enqueue(b); 21 | } 22 | void gap(int k) { 23 | forn(v, N){ 24 | if (height[v] < k) continue; 25 | count[height[v]]--; 26 | height[v] = max(height[v], N+1); 27 | count[height[v]]++; 28 | enqueue(v); 29 | } 30 | } 31 | void relabel(int v) { 32 | count[height[v]]--; 33 | height[v] = 2*N; 34 | forall(it, G[v]) 35 | if(it->snd) 36 | height[v] = min(height[v], height[it->fst] + 1); 37 | count[height[v]]++; 38 | enqueue(v); 39 | } 40 | ll maxflow() {//O(V^3) 41 | zero(height), zero(active), zero(count), zero(excess); 42 | count[0] = N-1; 43 | count[N] = 1; 44 | height[SRC] = N; 45 | active[SRC] = active[SNK] = true; 46 | forall(it, G[SRC]){ 47 | excess[SRC] += it->snd; 48 | push(SRC, it->fst); 49 | } 50 | while(sz(Q)) { 51 | int v = Q.front(); Q.pop(); 52 | active[v]=false; 53 | forall(it, G[v]) push(v, it->fst); 54 | if(excess[v] > 0) 55 | count[height[v]] == 1? gap(height[v]):relabel(v); 56 | } 57 | ll mf=0; 58 | forall(it, G[SRC]) mf+=G[it->fst][SRC]; 59 | return mf; 60 | } 61 | -------------------------------------------------------------------------------- /estructuras/rmq.lazy.cpp: -------------------------------------------------------------------------------- 1 | //Dado un arreglo y una operacion asociativa con neutro, get(i, j) opera sobre el rango [i, j). 2 | typedef int Elem;//Elem de los elementos del arreglo 3 | typedef int Alt;//Elem de la alteracion 4 | #define operacion(x,y) x+y 5 | const Elem neutro=0; const Alt neutro2=0; 6 | #define MAXN 100000 7 | struct RMQ{ 8 | int sz; 9 | Elem t[4*MAXN]; 10 | Alt dirty[4*MAXN];//las alteraciones pueden ser de distinto Elem 11 | Elem &operator[](int p){return t[sz+p];} 12 | void init(int n){//O(nlgn) 13 | sz = 1 << (32-__builtin_clz(n)); 14 | forn(i, 2*sz) t[i]=neutro; 15 | forn(i, 2*sz) dirty[i]=neutro2; 16 | } 17 | void push(int n, int a, int b){//propaga el dirty a sus hijos 18 | if(dirty[n]!=0){ 19 | t[n]+=dirty[n]*(b-a);//altera el nodo 20 | if(n=b) return neutro; 29 | push(n, a, b);//corrige el valor antes de usarlo 30 | if(i<=a && b<=j) return t[n]; 31 | int c=(a+b)/2; 32 | return operacion(get(i, j, 2*n, a, c), get(i, j, 2*n+1, c, b)); 33 | } 34 | Elem get(int i, int j){return get(i,j,1,0,sz);} 35 | //altera los valores en [i, j) con una alteracion de val 36 | void alterar(Alt val, int i, int j, int n, int a, int b){//O(lgn) 37 | push(n, a, b); 38 | if(j<=a || i>=b) return; 39 | if(i<=a && b<=j){ 40 | dirty[n]+=val; 41 | push(n, a, b); 42 | return; 43 | } 44 | int c=(a+b)/2; 45 | alterar(val, i, j, 2*n, a, c), alterar(val, i, j, 2*n+1, c, b); 46 | t[n]=operacion(t[2*n], t[2*n+1]);//por esto es el push de arriba 47 | } 48 | void alterar(Alt val, int i, int j){alterar(val,i,j,1,0,sz);} 49 | }rmq; 50 | -------------------------------------------------------------------------------- /estructuras/gain-cost.set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | #define dprint(v) cerr << #v"=" << v << endl //;) 10 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 11 | #define forn(i,n) forr(i,0,n) 12 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 13 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 14 | #define sz(c) ((int)c.size()) 15 | #define zero(v) memset(v, 0, sizeof(v)) 16 | typedef long long ll; 17 | typedef pair ii; 18 | #define INF 1e9 19 | 20 | //esta estructura mantiene pairs(beneficio, costo) 21 | //de tal manera que en el set quedan ordenados 22 | //por beneficio Y COSTO creciente. (va borrando los que no son optimos) 23 | struct V{ 24 | int gain, cost; 25 | bool operator<(const V &b)const{return gain s; 28 | void add(V x){ 29 | set::iterator p=s.lower_bound(x);//primer elemento mayor o igual 30 | if(p!=s.end() && p->cost <= x.cost) return;//ya hay uno mejor 31 | p=s.upper_bound(x);//primer elemento mayor 32 | if(p!=s.begin()){//borro todos los peores (<=beneficio y >=costo) 33 | --p;//ahora es ultimo elemento menor o igual 34 | while(p->cost >= x.cost){ 35 | if(p==s.begin()){s.erase(p); break;} 36 | s.erase(p--); 37 | } 38 | } 39 | s.insert(x); 40 | } 41 | int get(int gain){//minimo costo de obtener tal ganancia 42 | set::iterator p=s.lower_bound((V){gain, 0}); 43 | return p==s.end()? INF : p->cost;} 44 | 45 | int main() { 46 | V x; 47 | while(cout << "pair=", cin >> x.gain >> x.cost){ 48 | add(x); 49 | forall(it, s) cout << '(' << it->gain << ',' << it->cost << ") "; cout << endl; 50 | } 51 | return 0; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /grafos/diametro.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cout << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | typedef long long ll; 14 | typedef pair ii; 15 | const int MAXN=100100; 16 | 17 | vector G[MAXN]; int n,m,p[MAXN],d[MAXN],d2[MAXN]; 18 | int bfs(int r, int *d) { 19 | queue q; 20 | d[r]=0; q.push(r); 21 | int v; 22 | while(sz(q)) { v=q.front(); q.pop(); 23 | forall(it,G[v]) if (d[*it]==-1) 24 | d[*it]=d[v]+1, p[*it]=v, q.push(*it); 25 | } 26 | return v;//ultimo nodo visitado 27 | } 28 | vector diams; vector centros; 29 | void diametros(){ 30 | memset(d,-1,sizeof(d)); 31 | memset(d2,-1,sizeof(d2)); 32 | diams.clear(), centros.clear(); 33 | forn(i, n) if(d[i]==-1){ 34 | int v,c; 35 | c=v=bfs(bfs(i, d2), d); 36 | forn(_,d[v]/2) c=p[c]; 37 | diams.pb(d[v]); 38 | if(d[v]&1) centros.pb(ii(c, p[c])); 39 | else centros.pb(ii(c, c)); 40 | } 41 | } 42 | 43 | int main() { 44 | freopen("in", "r", stdin); 45 | while(cin >> n >> m){ 46 | forn(i,m) { int a,b; cin >> a >> b; a--, b--; 47 | G[a].pb(b); 48 | G[b].pb(a); 49 | } 50 | diametros(); 51 | cout << "Diametros: "; 52 | forall(it, diams) cout << *it << ' '; cout << endl; 53 | cout << "Centros:" << endl; 54 | forall(it, centros){ 55 | cout << '\t'; 56 | if(it->fst==it->snd) cout << it->fst+1 << endl; 57 | else cout << it->fst+1 << "-" << it->snd+1 << endl; 58 | } 59 | zero(G); 60 | } 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /grafos/chuliu.cpp: -------------------------------------------------------------------------------- 1 | void visit(graph &h, int v, int s, int r, 2 | vector &no, vector< vector > &comp, 3 | vector &prev, vector< vector > &next, vector &mcost, 4 | vector &mark, weight &cost, bool &found) { 5 | if (mark[v]) { 6 | vector temp = no; 7 | found = true; 8 | do { 9 | cost += mcost[v]; 10 | v = prev[v]; 11 | if (v != s) { 12 | while (comp[v].size() > 0) { 13 | no[comp[v].back()] = s; 14 | comp[s].push_back(comp[v].back()); 15 | comp[v].pop_back(); 16 | } 17 | } 18 | } while (v != s); 19 | forall(j,comp[s]) if (*j != r) forall(e,h[*j]) 20 | if (no[e->src] != s) e->w -= mcost[ temp[*j] ]; 21 | } 22 | mark[v] = true; 23 | forall(i,next[v]) if (no[*i] != no[v] && prev[no[*i]] == v) 24 | if (!mark[no[*i]] || *i == s) 25 | visit(h, *i, s, r, no, comp, prev, next, mcost, mark, cost, found); 26 | } 27 | weight minimumSpanningArborescence(const graph &g, int r) { 28 | const int n=sz(g); 29 | graph h(n); 30 | forn(u,n) forall(e,g[u]) h[e->dst].pb(*e); 31 | vector no(n); 32 | vector > comp(n); 33 | forn(u, n) comp[u].pb(no[u] = u); 34 | for (weight cost = 0; ;) { 35 | vector prev(n, -1); 36 | vector mcost(n, INF); 37 | forn(j,n) if (j != r) forall(e,h[j]) 38 | if (no[e->src] != no[j]) 39 | if (e->w < mcost[ no[j] ]) 40 | mcost[ no[j] ] = e->w, prev[ no[j] ] = no[e->src]; 41 | vector< vector > next(n); 42 | forn(u,n) if (prev[u] >= 0) 43 | next[ prev[u] ].push_back(u); 44 | bool stop = true; 45 | vector mark(n); 46 | forn(u,n) if (u != r && !mark[u] && !comp[u].empty()) { 47 | bool found = false; 48 | visit(h, u, u, r, no, comp, prev, next, mcost, mark, cost, found); 49 | if (found) stop = false; 50 | } 51 | if (stop) { 52 | forn(u,n) if (prev[u] >= 0) cost += mcost[u]; 53 | return cost; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /geometria/circle.cpp: -------------------------------------------------------------------------------- 1 | vec perp(vec v){return vec(-v.y, v.x);} 2 | line bisector(pto x, pto y){ 3 | line l=line(x, y); pto m=(x+y)/2; 4 | return line(-l.b, l.a, -l.b*m.x+l.a*m.y); 5 | } 6 | struct Circle{ 7 | pto o; 8 | double r; 9 | Circle(pto x, pto y, pto z){ 10 | o=inter(bisector(x, y), bisector(y, z)); 11 | r=dist(o, x); 12 | } 13 | pair ptosTang(pto p){ 14 | pto m=(p+o)/2; 15 | tipo d=dist(o, m); 16 | tipo a=r*r/(2*d); 17 | tipo h=sqrt(r*r-a*a); 18 | pto m2=o+(m-o)*a/d; 19 | vec per=perp(m-o)/d; 20 | return make_pair(m2-per*h, m2+per*h); 21 | } 22 | }; 23 | //finds the center of the circle containing p1 and p2 with radius r 24 | //as there may be two solutions swap p1, p2 to get the other 25 | bool circle2PtsRad(pto p1, pto p2, double r, pto &c){ 26 | double d2=(p1-p2).norm_sq(), det=r*r/d2-0.25; 27 | if(det<0) return false; 28 | c=(p1+p2)/2+perp(p2-p1)*sqrt(det); 29 | return true; 30 | } 31 | #define sqr(a) ((a)*(a)) 32 | #define feq(a,b) (fabs((a)-(b)) ecCuad(tipo a, tipo b, tipo c){//a*x*x+b*x+c=0 34 | tipo dx = sqrt(b*b-4.0*a*c); 35 | return make_pair((-b + dx)/(2.0*a),(-b - dx)/(2.0*a)); 36 | } 37 | pair interCL(Circle c, line l){ 38 | bool sw=false; 39 | if((sw=feq(0,l.b))){ 40 | swap(l.a, l.b); 41 | swap(c.o.x, c.o.y); 42 | } 43 | pair rc = ecCuad( 44 | sqr(l.a)+sqr(l.b), 45 | 2.0*l.a*l.b*c.o.y-2.0*(sqr(l.b)*c.o.x+l.c*l.a), 46 | sqr(l.b)*(sqr(c.o.x)+sqr(c.o.y)-sqr(c.r))+sqr(l.c)-2.0*l.c*l.b*c.o.y 47 | ); 48 | pair p( pto(rc.first, (l.c - l.a * rc.first) / l.b), 49 | pto(rc.second, (l.c - l.a * rc.second) / l.b) ); 50 | if(sw){ 51 | swap(p.first.x, p.first.y); 52 | swap(p.second.x, p.second.y); 53 | } 54 | return p; 55 | } 56 | pair interCC(Circle c1, Circle c2){ 57 | line l; 58 | l.a = c1.o.x-c2.o.x; 59 | l.b = c1.o.y-c2.o.y; 60 | l.c = (sqr(c2.r)-sqr(c1.r)+sqr(c1.o.x)-sqr(c2.o.x)+sqr(c1.o.y) 61 | -sqr(c2.o.y))/2.0; 62 | return interCL(c1, l); 63 | } 64 | -------------------------------------------------------------------------------- /grafos/heavylight.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define dprint(v) cerr << #v"=" << v << endl //;) 9 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 10 | #define forn(i,n) forr(i,0,n) 11 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 12 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 13 | #define sz(c) ((int)c.size()) 14 | #define zero(v) memset(v, 0, sizeof(v)) 15 | typedef long long ll; 16 | typedef pair ii; 17 | const int MAXN=100100; 18 | vector G[MAXN]; 19 | int n; 20 | 21 | int treesz[MAXN];//cantidad de nodos en el subarbol del nodo v 22 | int dad[MAXN];//dad[v]=padre del nodo v 23 | void dfs1(int v, int p=-1){//pre-dfs 24 | dad[v]=p; 25 | treesz[v]=1; 26 | forall(it, G[v]) if(*it!=p){ 27 | dfs1(*it, v); 28 | treesz[v]+=treesz[*it]; 29 | } 30 | } 31 | //PONER Q EN 0 !!!!! 32 | int pos[MAXN], q;//pos[v]=posicion del nodo v en el recorrido de la dfs 33 | //Las cadenas aparecen continuas en el recorrido! 34 | int cantcad; 35 | int homecad[MAXN];//dada una cadena devuelve su nodo inicial 36 | int cad[MAXN];//cad[v]=cadena a la que pertenece el nodo 37 | void heavylight(int v, int cur=-1){ 38 | if(cur==-1) homecad[cur=cantcad++]=v; 39 | pos[v]=q++; 40 | cad[v]=cur; 41 | int mx=-1; 42 | forn(i, sz(G[v])) if(G[v][i]!=dad[v]) 43 | if(mx==-1 || treesz[G[v][mx]]=b) return neutro; 31 | push(n, a, b);//corrige el valor antes de usarlo//* 32 | if(i<=a && b<=j) return t[n]; 33 | int c=(a+b)/2; 34 | return operacion(get(i, j, 2*n, a, c), get(i, j, 2*n+1, c, b)); 35 | } 36 | Elem get(int i, int j){return get(i,j,1,0,sz);} 37 | //altera los valores en [i, j) con una alteracion de val 38 | void alterar(Alt val, int i, int j, int n, int a, int b){//O(lgn)//* 39 | push(n, a, b); 40 | if(j<=a || i>=b) return; 41 | if(i<=a && b<=j){ 42 | dirty[n]+=val; 43 | push(n, a, b); 44 | return; 45 | } 46 | int c=(a+b)/2; 47 | alterar(val, i, j, 2*n, a, c), alterar(val, i, j, 2*n+1, c, b); 48 | t[n]=operacion(t[2*n], t[2*n+1]);//por esto es el push de arriba 49 | } 50 | void alterar(Alt val, int i, int j){alterar(val,i,j,1,0,sz);}//* 51 | void set(int p, tipo val){//O(lgn)//No usar con lazy!! 52 | for(p+=sz; p>0 && t[p]!=val;){ 53 | t[p]=val; 54 | p/=2; 55 | val=operacion(t[p*2], t[p*2+1]); 56 | } 57 | } 58 | }rmq; 59 | -------------------------------------------------------------------------------- /string/suffix.array.cpp: -------------------------------------------------------------------------------- 1 | #define MAX_N 1000 2 | #define rBOUND(x) (x=0) hi=mid; 44 | else lo=mid+1; 45 | } 46 | if(s.compare(sa[lo], sz(P), P)!=0) return ii(-1, -1); 47 | ii ans; ans.fst=lo; 48 | lo=0, hi=n-1, mid; 49 | while(lo0) hi=mid; 53 | else lo=mid+1; 54 | } 55 | if(s.compare(sa[hi], sz(P), P)!=0) hi--; 56 | ans.snd=hi; 57 | return ans; 58 | } 59 | 60 | //Calculates the LCP between consecutives suffixes in the Suffix Array. 61 | //LCP[i] is the length of the LCP between sa[i] and sa[i-1] 62 | int LCP[MAX_N], phi[MAX_N], PLCP[MAX_N]; 63 | void computeLCP(){//O(n) 64 | phi[sa[0]]=-1; 65 | forr(i, 1, n) phi[sa[i]]=sa[i-1]; 66 | int L=0; 67 | forn(i, n){ 68 | if(phi[i]==-1) {PLCP[i]=0; continue;} 69 | while(s[i+L]==s[phi[i]+L]) L++; 70 | PLCP[i]=L; 71 | L=max(L-1, 0); 72 | } 73 | forn(i, n) LCP[i]=PLCP[sa[i]]; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /estructuras/bigint.villa.cpp: -------------------------------------------------------------------------------- 1 | #define BASEXP 6 2 | #define BASE 1000000 3 | #define LMAX 1000 4 | struct bint{int l;ll n[LMAX];bint(ll x=0){l=1;forn(i,LMAX){if(x)l=i+1;n[i]=x%BASE;x/=BASE;}}bint(string x){l=(x.size()-1)/BASEXP+1;fill(n,n+LMAX,0);ll r=1;forn(i,sz(x)){n[i/BASEXP]+=r*(x[x.size()-1-i]-'0');r*=10;if(r==BASE)r=1;}}void out(){cout<1&&!n[l-1])l--;}};bint operator+(const bint&a,const bint&b){bint c;c.l=max(a.l,b.l);ll q=0;forn(i,c.l)q+=a.n[i]+b.n[i],c.n[i]=q%BASE,q/=BASE;if(q)c.n[c.l++]=q;c.invar();return c;}pairlresta(const bint&a,const bint&b){bint c;c.l=max(a.l,b.l);ll q=0;forn(i,c.l)q+=a.n[i]-b.n[i],c.n[i]=(q+BASE)%BASE,q=(q+BASE)/BASE-1;c.invar();return make_pair(c,!q);}bint&operator-=(bint&a,const bint&b){return a=lresta(a,b).first;}bint operator-(const bint&a,const bint&b){return lresta(a,b).first;}bool operator<(const bint&a,const bint&b){return!lresta(a,b).second;}bool operator<=(const bint&a,const bint&b){return lresta(b,a).second;}bool operator==(const bint&a,const bint&b){return a<=b&&b<=a;}bint operator*(const bint&a,ll b){bint c;ll q=0;forn(i,a.l)q+=a.n[i]*b,c.n[i]=q%BASE,q/=BASE;c.l=a.l;while(q)c.n[c.l++]=q%BASE,q/=BASE;c.invar();return c;}bint operator*(const bint&a,const bint&b){bint c;c.l=a.l+b.l;fill(c.n,c.n+b.l,0);forn(i,a.l){ll q=0;forn(j,b.l)q+=a.n[i]*b.n[j]+c.n[i+j],c.n[i+j]=q%BASE,q/=BASE;c.n[i+b.l]=q;}c.invar();return c;}pairldiv(const bint&a,ll b){bint c;ll rm=0;dforn(i,a.l){rm=rm*BASE+a.n[i];c.n[i]=rm/b;rm%=b;}c.l=a.l;c.invar();return make_pair(c,rm);}bint operator/(const bint&a,ll b){return ldiv(a,b).first;}ll operator%(const bint&a,ll b){return ldiv(a,b).second;}pairldiv(const bint&a,const bint&b){bint c;bint rm=0;dforn(i,a.l){if(rm.l==1&&!rm.n[0])rm.n[0]=a.n[i];else{dforn(j,rm.l)rm.n[j+1]=rm.n[j];rm.n[0]=a.n[i];rm.l++;}ll q=rm.n[b.l]*BASE+rm.n[b.l-1];ll u=q/(b.n[b.l-1]+1);ll v=q/b.n[b.l-1]+1;while(u 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | #define dprint(v) cerr << #v"=" << v << endl //;) 11 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 12 | #define forn(i,n) forr(i,0,n) 13 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 14 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 15 | #define sz(c) ((int)c.size()) 16 | #define zero(v) memset(v, 0, sizeof(v)) 17 | #define pb push_back 18 | #define fst first 19 | #define snd second 20 | typedef long long ll; 21 | typedef pair ii; 22 | 23 | typedef int tipo; 24 | tipo oper(const tipo &a, const tipo &b){ 25 | return a+b; 26 | } 27 | struct node{ 28 | tipo v; node *l,*r; 29 | node(tipo v):v(v), l(NULL), r(NULL) {} 30 | node(node *l, node *r) : l(l), r(r){ 31 | if(!l) v=r->v; 32 | else if(!r) v=l->v; 33 | else v=oper(l->v, r->v); 34 | } 35 | }; 36 | node *build (tipo *a, int tl, int tr) {//modificar para que tome tipo a 37 | if (tl+1==tr) return new node(a[tl]); 38 | int tm=(tl + tr)>>1; 39 | return new node(build(a, tl, tm), build(a, tm, tr)); 40 | } 41 | node *update(int pos, int new_val, node *t, int tl, int tr){ 42 | if (tl+1==tr) return new node(new_val); 43 | int tm=(tl+tr)>>1; 44 | if(pos < tm) return new node(update(pos, new_val, t->l, tl, tm), t->r); 45 | else return new node(t->l, update(pos, new_val, t->r, tm, tr)); 46 | } 47 | tipo get(int l, int r, node *t, int tl, int tr){ 48 | if(l==tl && tr==r) return t->v; 49 | int tm=(tl + tr)>>1; 50 | if(r<=tm) return get(l, r, t->l, tl, tm); 51 | else if(l>=tm) return get(l, r, t->r, tm, tr); 52 | return oper(get(l, tm, t->l, tl, tm), get(tm, r, t->r, tm, tr)); 53 | } 54 | 55 | int vv[10000]; 56 | 57 | int main() { 58 | //~ freopen("in", "r", stdin); 59 | int n=8, a,b; char c[10]; 60 | node *root=build(vv, 0, n); 61 | while(scanf("%s %d %d", c, &a, &b)>0){ 62 | if(tolower(c[0])=='s') root=update(a, b, root, 0, n); 63 | else printf("%d\n", get(a, b, root, 0, n)); 64 | } 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /estructuras/treap.hs: -------------------------------------------------------------------------------- 1 | module Treap where 2 | --Es una implementación (parcial) del TAD conjunto. 3 | --Guarda un conjunto de keys 4 | --A cada key le asigna una prioridad random. 5 | 6 | -- T prioridad left key right 7 | data Treap a = E | T Int (Treap a) a (Treap a) deriving Show 8 | 9 | --Invariantes: 10 | --Mirando las key, el treap es un arbol de busqueda 11 | --Mirando las prioridades, el treap es un max-heap! 12 | 13 | emptyT :: Treap a 14 | emptyT = E 15 | 16 | --mergea dos treaps, debe cumplirse que todas las key de l < las de r 17 | --por lo tanto esta no es una funcion de mergeo general. 18 | mergeT :: Treap a -> Treap a -> Treap a 19 | mergeT E r = r 20 | mergeT l E = l 21 | mergeT l@(T lp ll lv lr) r@(T rp rl rv rr) | lp < rp = T lp ll lv (mergeT lr r) 22 | | otherwise = T rp (mergeT l rl) rv rr 23 | 24 | --dado una key, parte un treap en dos segun una key. 25 | --los de la izquierda tienen key menores, los de la derecha, mayores 26 | splitT :: Ord a => Treap a -> a -> (Treap a, Treap a) 27 | splitT E k = (E, E) 28 | splitT (T p l v r) k | k<=v = let (l', r') = splitT l k 29 | in (l', T p r' v r) 30 | | otherwise = let (l', r') = splitT r k 31 | in (T p l v l', r') 32 | 33 | singletonT :: a -> Int -> Treap a 34 | singletonT k elrandom = T elrandom E k E 35 | 36 | insertT :: Ord a => Treap a -> a -> Int -> Treap a 37 | insertT t k elrandom = mergeT (mergeT l (singletonT k elrandom)) r 38 | where (l, r) = splitT t k 39 | 40 | --implementacion clasica, borra una key a lo BST 41 | eraseT :: Ord a => Treap a -> a -> Treap a 42 | eraseT (T p l v r) k | k==v = mergeT l r 43 | | kv = T p l v (eraseT r k) 45 | 46 | --borra todas las keys en un rango... en O(log n) !! :O omg 47 | erasesT :: Ord a => Treap a -> a -> a -> Treap a 48 | erasesT t l r = mergeT t1 t4 49 | where (t1, t2) = splitT t l 50 | (t3, t4) = splitT t2 r 51 | 52 | 53 | --Todas las operaciones son O(log n) (amortizado) 54 | -------------------------------------------------------------------------------- /geometria/int.circs.cpp: -------------------------------------------------------------------------------- 1 | struct event { 2 | double x; int t; 3 | event(double xx, int tt) : x(xx), t(tt) {} 4 | bool operator <(const event &o) const { return x < o.x; } 5 | }; 6 | typedef vector VC; 7 | typedef vector VE; 8 | int n; 9 | double cuenta(VE &v, double A,double B) { 10 | sort(v.begin(), v.end()); 11 | double res = 0.0, lx = ((v.empty())?0.0:v[0].x); 12 | int contador = 0; 13 | forn(i,sz(v)) { 14 | //interseccion de todos (contador == n), union de todos (contador > 0) 15 | //conjunto de puntos cubierto por exacta k Circulos (contador == k) 16 | if (contador == n) res += v[i].x - lx; 17 | contador += v[i].t, lx = v[i].x; 18 | } 19 | return res; 20 | } 21 | // Primitiva de sqrt(r*r - x*x) como funcion double de una variable x. 22 | inline double primitiva(double x,double r) { 23 | if (x >= r) return r*r*M_PI/4.0; 24 | if (x <= -r) return -r*r*M_PI/4.0; 25 | double raiz = sqrt(r*r-x*x); 26 | return 0.5 * (x * raiz + r*r*atan(x/raiz)); 27 | } 28 | double interCircle(VC &v) { 29 | vector p; p.reserve(v.size() * (v.size() + 2)); 30 | forn(i,sz(v)) p.push_back(v[i].c.x + v[i].r), p.push_back(v[i].c.x - v[i].r); 31 | forn(i,sz(v)) forn(j,i) { 32 | Circle &a = v[i], b = v[j]; 33 | double d = (a.c - b.c).norm(); 34 | if (fabs(a.r - b.r) < d && d < a.r + b.r) { 35 | double alfa = acos((sqr(a.r) + sqr(d) - sqr(b.r)) / (2.0 * d * a.r)); 36 | pto vec = (b.c - a.c) * (a.r / d); 37 | p.pb((a.c + rotate(vec, alfa)).x), p.pb((a.c + rotate(vec, -alfa)).x); 38 | } 39 | } 40 | sort(p.begin(), p.end()); 41 | double res = 0.0; 42 | forn(i,sz(p)-1) { 43 | const double A = p[i], B = p[i+1]; 44 | VE ve; ve.reserve(2 * v.size()); 45 | forn(j,sz(v)) { 46 | const Circle &c = v[j]; 47 | double arco = primitiva(B-c.c.x,c.r) - primitiva(A-c.c.x,c.r); 48 | double base = c.c.y * (B-A); 49 | ve.push_back(event(base + arco,-1)); 50 | ve.push_back(event(base - arco, 1)); 51 | } 52 | res += cuenta(ve,A,B); 53 | } 54 | return res; 55 | } 56 | -------------------------------------------------------------------------------- /grafos/hungarian.cpp: -------------------------------------------------------------------------------- 1 | #define tipo double 2 | const tipo EPS = 1e-9; 3 | const tipo INF = 1e14; 4 | #define N 502 5 | //Dado un grafo bipartito completo con costos no negativos, encuentra el matching perfecto de minimo costo. 6 | tipo cost[N][N], lx[N], ly[N], slack[N]; //llenar: cost=matriz de adyacencia 7 | int n, max_match, xy[N], yx[N], slackx[N],prev2[N];//n=cantidad de nodos 8 | bool S[N], T[N]; //sets S and T in algorithm 9 | void add_to_tree(int x, int prevx) { 10 | S[x] = true, prev2[x] = prevx; 11 | forn(y, n) if (lx[x] + ly[y] - cost[x][y] < slack[y] - EPS) 12 | slack[y] = lx[x] + ly[y] - cost[x][y], slackx[y] = x; 13 | } 14 | void update_labels(){ 15 | tipo delta = INF; 16 | forn (y, n) if (!T[y]) delta = min(delta, slack[y]); 17 | forn (x, n) if (S[x]) lx[x] -= delta; 18 | forn (y, n) if (T[y]) ly[y] += delta; else slack[y] -= delta; 19 | } 20 | void init_labels(){ 21 | zero(lx), zero(ly); 22 | forn (x,n) forn(y,n) lx[x] = max(lx[x], cost[x][y]); 23 | } 24 | void augment() { 25 | if (max_match == n) return; 26 | int x, y, root, q[N], wr = 0, rd = 0; 27 | memset(S, false, sizeof(S)), memset(T, false, sizeof(T)); 28 | memset(prev2, -1, sizeof(prev2)); 29 | forn (x, n) if (xy[x] == -1){ 30 | q[wr++] = root = x, prev2[x] = -2; 31 | S[x] = true; break; } 32 | forn (y, n) slack[y] = lx[root] + ly[y] - cost[root][y], slackx[y] = root; 33 | while (true){ 34 | while (rd < wr){ 35 | x = q[rd++]; 36 | for (y = 0; y < n; y++) if (cost[x][y] == lx[x] + ly[y] && !T[y]){ 37 | if (yx[y] == -1) break; T[y] = true; 38 | q[wr++] = yx[y], add_to_tree(yx[y], x); } 39 | if (y < n) break; } 40 | if (y < n) break; 41 | update_labels(), wr = rd = 0; 42 | for (y = 0; y < n; y++) if (!T[y] && slack[y] == 0){ 43 | if (yx[y] == -1){x = slackx[y]; break;} 44 | else{ 45 | T[y] = true; 46 | if (!S[yx[y]]) q[wr++] = yx[y], add_to_tree(yx[y], slackx[y]); 47 | }} 48 | if (y < n) break; } 49 | if (y < n){ 50 | max_match++; 51 | for (int cx = x, cy = y, ty; cx != -2; cx = prev2[cx], cy = ty) 52 | ty = xy[cx], yx[cy] = cx, xy[cx] = cy; 53 | augment(); } 54 | } 55 | tipo hungarian(){ 56 | tipo ret = 0; max_match = 0, memset(xy, -1, sizeof(xy)); 57 | memset(yx, -1, sizeof(yx)), init_labels(), augment(); //steps 1-3 58 | forn (x,n) ret += cost[x][xy[x]]; return ret; 59 | } 60 | -------------------------------------------------------------------------------- /string/suffix.automaton.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cerr << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | typedef long long ll; 14 | typedef pair ii; 15 | 16 | struct state { 17 | int len, link; 18 | map next; 19 | state() { } 20 | }; 21 | const int MAXLEN = 10010; 22 | state st[MAXLEN*2]; 23 | int sz, last; 24 | void sa_init() { 25 | forn(i,sz) st[i].next.clear(); 26 | sz = last = 0; 27 | st[0].len = 0; 28 | st[0].link = -1; 29 | ++sz; 30 | } 31 | // Es un DAG de una sola fuente y una sola hoja 32 | // cantidad de endpos = cantidad de apariciones = cantidad de caminos de la clase al nodo terminal 33 | // cantidad de miembros de la clase = st[v].len-st[st[v].link].len (v>0) = caminos del inicio a la clase 34 | // El arbol de los suffix links es el suffix tree de la cadena invertida. La string de la arista link(v)->v son los caracteres que difieren 35 | void sa_extend (char c) { 36 | int cur = sz++; 37 | st[cur].len = st[last].len + 1; 38 | // en cur agregamos la posicion que estamos extendiendo 39 | //podria agregar tambien un identificador de las cadenas a las cuales pertenece (si hay varias) 40 | int p; 41 | for (p=last; p!=-1 && !st[p].next.count(c); p=st[p].link) // modificar esta linea para hacer separadores unicos entre varias cadenas (c=='$') 42 | st[p].next[c] = cur; 43 | if (p == -1) 44 | st[cur].link = 0; 45 | else { 46 | int q = st[p].next[c]; 47 | if (st[p].len + 1 == st[q].len) 48 | st[cur].link = q; 49 | else { 50 | int clone = sz++; 51 | // no le ponemos la posicion actual a clone sino indirectamente por el link de cur 52 | st[clone].len = st[p].len + 1; 53 | st[clone].next = st[q].next; 54 | st[clone].link = st[q].link; 55 | for (; p!=-1 && st[p].next.count(c) && st[p].next[c]==q; p=st[p].link) 56 | st[p].next[c] = clone; 57 | st[q].link = st[cur].link = clone; 58 | } 59 | } 60 | last = cur; 61 | } 62 | 63 | int main() { 64 | string s; cin >> s; 65 | sa_init(); 66 | forn(i, sz(s)) sa_extend(s[i]); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /grafos/biconexas.bridge.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | #define dprint(v) cerr << #v"=" << v << endl //;) 10 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 11 | #define forn(i,n) forr(i,0,n) 12 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 13 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 14 | #define sz(c) ((int)c.size()) 15 | #define zero(v) memset(v, 0, sizeof(v)) 16 | #define fst first 17 | #define snd second 18 | 19 | #define pb push_back 20 | typedef long long ll; 21 | typedef pair ii; 22 | #define pb push_back 23 | 24 | const int MAXN=1010; 25 | int n, m; 26 | vector G[MAXN]; 27 | 28 | struct edge { 29 | int u,v, comp; 30 | bool bridge; 31 | }; 32 | vector e; 33 | void addEdge(int u, int v) { 34 | G[u].pb(sz(e)), G[v].pb(sz(e)); 35 | e.pb((edge){u,v,-1,false}); 36 | } 37 | //d[i]=id de la dfs 38 | //b[i]=lowest id reachable from i 39 | int d[MAXN], b[MAXN], t; 40 | int nbc;//cant componentes 41 | int comp[MAXN];//comp[i]=cant comp biconexas a la cual pertenece i 42 | void initDfs(int n) { 43 | zero(G), zero(comp); 44 | e.clear(); 45 | forn(i,n) d[i]=-1; 46 | nbc = t = 0; 47 | } 48 | stack st; 49 | void dfs(int u, int pe) {//O(n + m) 50 | b[u] = d[u] = t++; 51 | comp[u] = (pe != -1); 52 | forall(ne, G[u]) if (*ne != pe){ 53 | int v = e[*ne].u ^ e[*ne].v ^ u; 54 | if (d[v] == -1) { 55 | st.push(*ne); 56 | dfs(v,*ne); 57 | if (b[v] > d[u]){ 58 | e[*ne].bridge = true; // bridge 59 | } 60 | if (b[v] >= d[u]){ // art 61 | int last; 62 | do { 63 | last = st.top(); st.pop(); 64 | e[last].comp = nbc; 65 | } while (last != *ne); 66 | nbc++; 67 | comp[u]++; 68 | } 69 | b[u] = min(b[u], b[v]); 70 | } 71 | else if (d[v] < d[u]) { // back edge 72 | st.push(*ne); 73 | b[u] = min(b[u], d[v]); 74 | } 75 | } 76 | } 77 | 78 | int main() { 79 | //~ freopen("in", "r", stdin); 80 | while(cin >> n >> m){ 81 | initDfs(n); 82 | forn(i, m){ 83 | int a,b; cin >> a >> b; 84 | addEdge(a,b); 85 | } 86 | forn(i, n) cout << "comp[" << i << "] = " << comp[i] << endl; 87 | forall(ne, e) cout << ne->u << "->" << ne->v << " en la comp. " << ne->comp << endl; 88 | cout << "Cant. de componentes biconexas = " << nbc << endl; 89 | } 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /math/determinante.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cerr << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | typedef long long ll; 14 | typedef pair ii; 15 | 16 | 17 | struct Mat { 18 | vector > vec; 19 | Mat(int n): vec(n, vector(n) ) {} 20 | Mat(int n, int m): vec(n, vector(m) ) {} 21 | vector &operator[](int f){return vec[f];} 22 | const vector &operator[](int f) const {return vec[f];} 23 | int size() const {return sz(vec);} 24 | Mat operator+(Mat &b) { ///this de n x m entonces b de n x m 25 | Mat m(sz(b),sz(b[0])); 26 | forn(i,sz(vec)) forn(j,sz(vec[0])) m[i][j] = vec[i][j] + b[i][j]; 27 | return m; } 28 | Mat operator*(const Mat &b) { ///this de n x m entonces b de m x t 29 | int n = sz(vec), m = sz(vec[0]), t = sz(b[0]); 30 | Mat mat(n,t); 31 | forn(i,n) forn(j,t) forn(k,m) mat[i][j] += vec[i][k] * b[k][j]; 32 | return mat; } 33 | double determinant(){//sacado de e maxx ru 34 | double det = 1; 35 | int n = sz(vec); 36 | Mat m(*this); 37 | forn(i, n){//para cada columna 38 | int k = i; 39 | forr(j, i+1, n)//busco la fila con mayor val abs 40 | if(abs(m[j][i])>abs(m[k][i])) k = j; 41 | if(abs(m[k][i])<1e-9) return 0; 42 | m[i].swap(m[k]);//la swapeo 43 | if(i!=k) det = -det; 44 | det *= m[i][i]; 45 | forr(j, i+1, n) m[i][j] /= m[i][i]; 46 | //hago 0 todas las otras filas 47 | forn(j, n) if (j!= i && abs(m[j][i])>1e-9) 48 | forr(k, i+1, n) m[j][k]-=m[i][k]*m[j][i]; 49 | } 50 | return det; 51 | } 52 | }; 53 | 54 | int n; 55 | int main() { 56 | //DETERMINANTE: 57 | //https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=625 58 | freopen("input.in", "r", stdin); 59 | ios::sync_with_stdio(0); 60 | while(cin >> n && n){ 61 | Mat m(n); 62 | forn(i, n) forn(j, n) cin >> m[i][j]; 63 | cout << (ll)round(m.determinant()) << endl; 64 | } 65 | cout << "*" << endl; 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /flow/dinic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | typedef long long ll; 5 | #define forall(it,v) for(auto it=v.begin();it!=v.end();++it) 6 | #define zero(v) memset(v, 0, sizeof(v)) 7 | #define pb push_back 8 | #define sz(v) ((int)v.size()) 9 | #define INF 1e18 10 | 11 | const int MAX = 300; 12 | // Corte minimo: vertices con dist[v]>=0 (del lado de src) VS. dist[v]==-1 (del lado del dst) 13 | // Para el caso de la red de Bipartite Matching (Sean V1 y V2 los conjuntos mas proximos a src y dst respectivamente): 14 | // Reconstruir matching: para todo v1 en V1 ver las aristas a vertices de V2 con it->f>0, es arista del Matching 15 | // Min Vertex Cover: vertices de V1 con dist[v]==-1 + vertices de V2 con dist[v]>0 16 | // Max Independent Set: tomar los vertices NO tomados por el Min Vertex Cover 17 | // Max Clique: construir la red de G complemento (debe ser bipartito!) y encontrar un Max Independet Set 18 | // Min Edge Cover: tomar las aristas del matching + para todo vertices no cubierto hasta el momento, tomar cualquier arista de el 19 | int nodes, src, dst; 20 | int dist[MAX], q[MAX], work[MAX]; 21 | struct Edge { 22 | int to, rev; 23 | ll f, cap; 24 | Edge(int to, int rev, ll f, ll cap) : to(to), rev(rev), f(f), cap(cap) {} 25 | }; 26 | vector G[MAX]; 27 | void addEdge(int s, int t, ll cap){ 28 | G[s].pb(Edge(t, sz(G[t]), 0, cap)), G[t].pb(Edge(s, sz(G[s])-1, 0, 0));} 29 | bool dinic_bfs(){ 30 | fill(dist, dist+nodes, -1), dist[src]=0; 31 | int qt=0; q[qt++]=src; 32 | for(int qh=0; qhto; 36 | if(dist[v]<0 && e->f < e->cap) 37 | dist[v]=dist[u]+1, q[qt++]=v; 38 | } 39 | } 40 | return dist[dst]>=0; 41 | } 42 | ll dinic_dfs(int u, ll f){ 43 | if(u==dst) return f; 44 | for(int &i=work[u]; i0){ 51 | e.f+=df, G[v][e.rev].f-= df; 52 | return df; } 53 | } 54 | } 55 | return 0; 56 | } 57 | ll maxFlow(int _src, int _dst){ 58 | src=_src, dst=_dst; 59 | ll result=0; 60 | while(dinic_bfs()){ 61 | fill(work, work+nodes, 0); 62 | while(ll delta=dinic_dfs(src,INF)) 63 | result+=delta; 64 | } 65 | // todos los nodos con dist[v]!=-1 vs los que tienen dist[v]==-1 forman el min-cut 66 | return result; } 67 | -------------------------------------------------------------------------------- /math/fft.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cerr << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | typedef long long ll; 14 | typedef pair ii; 15 | 16 | //~ typedef complex base; //menos codigo, pero mas lento 17 | //elegir si usar complejos de c (lento) o estos 18 | struct base{ 19 | double r,i; 20 | base(double r=0, double i=0):r(r), i(i){} 21 | double real()const{return r;} 22 | void operator/=(const int c){r/=c, i/=c;} 23 | }; 24 | base operator*(const base &a, const base &b){ 25 | return base(a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r);} 26 | base operator+(const base &a, const base &b){ 27 | return base(a.r+b.r, a.i+b.i);} 28 | base operator-(const base &a, const base &b){ 29 | return base(a.r-b.r, a.i-b.i);} 30 | vector rev; vector wlen_pw; 31 | inline static void fft(base a[], int n, bool invert) { 32 | forn(i, n) if(i>1; 36 | base wlen (cos(ang), sin(ang)); 37 | wlen_pw[0] = base (1, 0); 38 | forr(i, 1, len2) wlen_pw[i] = wlen_pw[i-1] * wlen; 39 | for (int i=0; i &a, const vector &b, vector &res) { 54 | vector fa (a.begin(), a.end()), fb (b.begin(), b.end()); 55 | int n=1; while(n < max(sz(a), sz(b))) n <<= 1; n <<= 1; 56 | calc_rev(n); 57 | fa.resize (n), fb.resize (n); 58 | fft (&fa[0], n, false), fft (&fb[0], n, false); 59 | forn(i, n) fa[i] = fa[i] * fb[i]; 60 | fft (&fa[0], n, true); 61 | res.resize(n); 62 | forn(i, n) res[i] = int (fa[i].real() + 0.5); } 63 | void toPoly(const string &s, vector &P){//convierte un numero a polinomio 64 | P.clear(); 65 | dforn(i, sz(s)) P.pb(s[i]-'0');} 66 | -------------------------------------------------------------------------------- /math/eclineales.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | #define dprint(v) cerr << #v"=" << v << endl //;) 10 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 11 | #define forn(i,n) forr(i,0,n) 12 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 13 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 14 | #define sz(c) ((int)c.size()) 15 | #define zero(v) memset(v, 0, sizeof(v)) 16 | #define fst first 17 | #define snd second 18 | 19 | #define pb push_back 20 | typedef long long ll; 21 | typedef pair ii; 22 | 23 | typedef double tipo; 24 | typedef vector Vec; 25 | typedef vector Mat; 26 | #define eps 1e-10 27 | #define feq(a, b) (fabs((a)-(b)) p; forn(i,m) p.push_back(i); 32 | forn(i, rw) { 33 | int uc=i, uf=i; 34 | forr(f, i, n) forr(c, i, m) if(fabs(a[f][c])>fabs(a[uf][uc])) {uf=f;uc=c;} 35 | if (feq(a[uf][uc], 0)) { rw = i; break; } 36 | forn(j, n) swap(a[j][i], a[j][uc]); 37 | swap(a[i], a[uf]); swap(y[i], y[uf]); swap(p[i], p[uc]); 38 | tipo inv = 1 / a[i][i]; //aca divide 39 | forr(j, i+1, n) { 40 | tipo v = a[j][i] * inv; 41 | forr(k, i, m) a[j][k]-=v * a[i][k]; 42 | y[j] -= v*y[i]; 43 | } 44 | } // rw = rango(a), aca la matriz esta triangulada 45 | forr(i, rw, n) if (!feq(y[i],0)) return false; // checkeo de compatibilidad 46 | x = vector(m, 0); 47 | dforn(i, rw){ 48 | tipo s = y[i]; 49 | forr(j, i+1, rw) s -= a[i][j]*x[p[j]]; 50 | x[p[i]] = s / a[i][i]; //aca divide 51 | } 52 | ev = Mat(m-rw, Vec(m, 0)); // Esta parte va SOLO si se necesita el ev 53 | forn(k, m-rw) { 54 | ev[k][p[k+rw]] = 1; 55 | dforn(i, rw){ 56 | tipo s = -a[i][k+rw]; 57 | forr(j, i+1, rw) s -= a[i][j]*ev[k][p[j]]; 58 | ev[k][p[i]] = s / a[i][i]; //aca divide 59 | } 60 | } 61 | return true; 62 | } 63 | 64 | 65 | int n,m; 66 | 67 | int main() { 68 | freopen("test", "r", stdin); 69 | while(cin >> n >> m){ 70 | vector< vector > A,Av; 71 | vector< double > b,x; 72 | 73 | A.resize(n); x.resize(n); b.resize(n); Av.resize(n); 74 | forn(i,n) { 75 | A[i].resize(m); 76 | Av[i].resize(m); 77 | } 78 | 79 | forn(i,n) forn(j,m) cin >> A[i][j]; 80 | forn(i,n) cin >> b[i]; 81 | 82 | resolver_ev(A,b,x,Av); 83 | 84 | forn(i,n) cout << " " << x[i]; 85 | cout << endl; 86 | dprint("ev"); 87 | forn(i,n) { 88 | forn(j,m) cout << Av[i][j]<< " "; 89 | cout << endl; 90 | } 91 | } 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /flow/min.cost.max.flow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cout << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | 14 | typedef long long ll; 15 | 16 | const int MAXN=10000; 17 | typedef ll tf; 18 | typedef ll tc; 19 | const tf INFFLUJO = 1e14; 20 | const tc INFCOSTO = 1e14; 21 | struct edge { 22 | int u, v; 23 | tf cap, flow; 24 | tc cost; 25 | tf rem() { return cap - flow; } 26 | }; 27 | int nodes; //numero de nodos 28 | vector G[MAXN]; // limpiar! 29 | vector e; // limpiar! 30 | void addEdge(int u, int v, tf cap, tc cost) { 31 | G[u].pb(sz(e)); e.pb((edge){u,v,cap,0,cost}); 32 | G[v].pb(sz(e)); e.pb((edge){v,u,0,0,-cost}); 33 | } 34 | tc dist[MAXN], mnCost; 35 | int pre[MAXN]; 36 | tf cap[MAXN], mxFlow; 37 | bool in_queue[MAXN]; 38 | void flow(int s, int t) { 39 | zero(in_queue); 40 | mxFlow=mnCost=0; 41 | while(1){ 42 | fill(dist, dist+nodes, INFCOSTO); dist[s] = 0; 43 | memset(pre, -1, sizeof(pre)); pre[s]=0; 44 | zero(cap); cap[s] = INFFLUJO; 45 | queue q; q.push(s); in_queue[s]=1; 46 | while(sz(q)){ 47 | int u=q.front(); q.pop(); in_queue[u]=0; 48 | for(auto it:G[u]) { 49 | edge &E = e[it]; 50 | if(E.rem() && dist[E.v] > dist[u] + E.cost + 1e-9){ // ojo EPS 51 | dist[E.v]=dist[u]+E.cost; 52 | pre[E.v] = it; 53 | cap[E.v] = min(cap[u], E.rem()); 54 | if(!in_queue[E.v]) q.push(E.v), in_queue[E.v]=1; 55 | } 56 | } 57 | } 58 | if (pre[t] == -1) break; 59 | mxFlow +=cap[t]; 60 | mnCost +=cap[t]*dist[t]; 61 | for (int v = t; v != s; v = e[pre[v]].u) { 62 | e[pre[v]].flow += cap[t]; 63 | e[pre[v]^1].flow -= cap[t]; 64 | } 65 | } 66 | } 67 | 68 | 69 | int u[MAXN],v[MAXN]; 70 | ll cst[MAXN],D,K; 71 | 72 | int main() { 73 | //problema ejemplo uva 10594 74 | //http://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=1535 75 | //~ freopen("in", "r", stdin); 76 | int N, M; 77 | while(cin >> N >> M){ 78 | zero(G), e.clear(); 79 | forn(i, M){ 80 | scanf("%d %d %lld",&u[i],&v[i],&cst[i]); 81 | --u[i], --v[i]; 82 | } 83 | scanf("%lld %lld",&D,&K); 84 | addEdge(0,1,D,0); 85 | 86 | forn(i, M){ 87 | addEdge(u[i]+1,v[i]+1,K,cst[i]); 88 | addEdge(v[i]+1,u[i]+1,K,cst[i]); 89 | } 90 | nodes = N+1; 91 | flow(0,N); 92 | if(mxFlow!=D) printf("Impossible.\n"); 93 | else printf("%lld\n", mnCost); 94 | } 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /algorithm.tex: -------------------------------------------------------------------------------- 1 | \#include $<$algorithm$>$ \#include $<$numeric$>$ \\ 2 | \begin{tabular}{|l|l|p{5.4cm}|} \hline 3 | \textbf{Algo} & \textbf{Params} & \textbf{Funcion} \\ \hline 4 | %swap & e1, e2 & da vuelta e1,e2 & $1$\\\hline 5 | sort, stable\_sort & f, l & ordena el intervalo \\ \hline 6 | %is\_sorted & f, l & \textit{bool} si esta ordenado \\ \hline 7 | nth\_element & f, nth, l & \textit{void} ordena el n-esimo, y \\ && particiona el resto \\ \hline 8 | fill, fill\_n & f, l / n, elem & \textit{void} llena [f, l) o [f, \\ && f+n) con elem \\ \hline 9 | lower\_bound, upper\_bound & f, l, elem & \textit{it} al primer / ultimo donde se \\ && puede insertar elem para que\\ && quede ordenada \\ \hline 10 | binary\_search & f, l, elem & \textit{bool} esta elem en [f, l) \\ \hline 11 | copy & f, l, resul & hace resul+$i$=f+$i$ $\forall i$ \\ \hline 12 | find, find\_if, find\_first\_of & f, l, elem & \textit{it} encuentra i $\in$[f,l) tq. i$=$elem, \\ & / pred / f2, l2 & pred(i), i$\in$[f2,l2)\\\hline 13 | count, count\_if & f, l, elem/pred & cuenta elem, pred(i)\\\hline 14 | search & f, l, f2, l2 & busca [f2,l2) $\in$ [f,l)\\\hline 15 | replace, replace\_if & f, l, old & cambia old / pred(i) por new \\ & / pred, new &\\\hline 16 | reverse & f, l & da vuelta\\\hline 17 | partition, stable\_partition & f, l, pred & pred(i) ad, !pred(i) atras\\\hline 18 | %min, max & e1, e2 & men / may & $1$\\\hline 19 | min\_element, max\_element & f, l, [comp] & \textit{it} min, max de [f,l]\\\hline 20 | lexicographical\_compare & f1,l1,f2,l2 & \textit{bool} con [f1,l1]<[f2,l2]\\\hline 21 | next/prev\_permutation & f,l & deja en [f,l) la perm sig, ant\\\hline 22 | set\_intersection, & f1, l1, f2, l2, res & [res, $\ldots$) la op. de conj\\ 23 | set\_difference, set\_union, & & \\ 24 | set\_symmetric\_difference, & &\\\hline 25 | push\_heap, pop\_heap, & f, l, e / e / & mete/saca e en heap [f,l), \\ 26 | make\_heap & & hace un heap de [f,l)\\\hline 27 | is\_heap & f,l & \textit{bool} es [f,l) un heap\\\hline 28 | accumulate & f,l,i,[op] & \textit{T} $=$ $\sum$/oper de [f,l)\\\hline 29 | inner\_product & f1, l1, f2, i & \textit{T} $=$ i $+$ [f1, l1) . [f2, $\ldots$ )\\\hline 30 | partial\_sum & f, l, r, [op] & r+i = $\sum$/oper de [f,f+i] $\forall i \in$[f,l)\\\hline 31 | %power & e, i, op & \textit{T} = $e^{n}$\\\hline 32 | \_\_builtin\_ffs& unsigned int & Pos. del primer 1 desde la derecha\\\hline 33 | \_\_builtin\_clz & unsigned int & Cant. de ceros desde la izquierda.\\\hline 34 | \_\_builtin\_ctz & unsigned int & Cant. de ceros desde la derecha.\\\hline 35 | \_\_builtin\_popcount & unsigned int & Cant. de 1’s en x.\\\hline 36 | \_\_builtin\_parity & unsigned int & 1 si x es par, 0 si es impar.\\\hline 37 | \_\_builtin\_XXXXXXll & unsigned ll & = pero para long long's.\\\hline 38 | \end{tabular}\newpage 39 | -------------------------------------------------------------------------------- /math/phollards.rho.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | #define dprint(v) cerr << #v"=" << v << endl //;) 12 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 13 | #define forn(i,n) forr(i,0,n) 14 | typedef long long ll; 15 | 16 | ll gcd(ll a, ll b){return a?gcd(b %a, a):b;} 17 | 18 | ll mulmod (ll a, ll b, ll c) { //returns (a*b)%c, and minimize overfloor 19 | ll x = 0, y = a%c; 20 | while (b > 0){ 21 | if (b % 2 == 1) x = (x+y) % c; 22 | y = (y*2) % c; 23 | b /= 2; 24 | } 25 | return x % c; 26 | } 27 | 28 | ll expmod (ll b, ll e, ll m){//O(log b) 29 | if(!e) return 1; 30 | ll q= expmod(b,e/2,m); q=mulmod(q,q,m); 31 | return e%2? mulmod(b,q,m) : q; 32 | } 33 | 34 | bool es_primo_prob (ll n, int a) 35 | { 36 | if (n == a) return true; 37 | ll s = 0,d = n-1; 38 | while (d % 2 == 0) s++,d/=2; 39 | 40 | ll x = expmod(a,d,n); 41 | if ((x == 1) || (x+1 == n)) return true; 42 | 43 | forn (i, s-1){ 44 | x = mulmod(x, x, n); 45 | if (x == 1) return false; 46 | if (x+1 == n) return true; 47 | } 48 | return false; 49 | } 50 | 51 | bool rabin (ll n){ //devuelve true si n es primo 52 | if (n == 1) return false; 53 | const int ar[] = {2,3,5,7,11,13,17,19,23}; 54 | forn (j,9) 55 | if (!es_primo_prob(n,ar[j])) 56 | return false; 57 | return true; 58 | } 59 | 60 | ll rho(ll n){ 61 | if( (n & 1) == 0 ) return 2; 62 | ll x = 2 , y = 2 , d = 1; 63 | ll c = rand() % n + 1; 64 | while( d == 1 ){ 65 | x = (mulmod( x , x , n ) + c)%n; 66 | y = (mulmod( y , y , n ) + c)%n; 67 | y = (mulmod( y , y , n ) + c)%n; 68 | if( x - y >= 0 ) d = gcd( x - y , n ); 69 | else d = gcd( y - x , n ); 70 | } 71 | return d==n? rho(n):d; 72 | } 73 | 74 | map prim; 75 | void factRho (ll n){ //O (lg n)^3. un solo numero 76 | if (n == 1) return; 77 | if (rabin(n)){ 78 | prim[n]++; 79 | return; 80 | } 81 | ll factor = rho(n); 82 | factRho(factor); 83 | factRho(n/factor); 84 | } 85 | 86 | 87 | int main(){ 88 | ll n; 89 | while(1){ 90 | n=abs((ll)rand()*rand()*rand()%(ll(1e18))+50); 91 | dprint(n); 92 | if(!rabin(n)){ 93 | //~ dprint(n); 94 | ll ans = rho (n); 95 | assert(!(n%ans) && ans>0); 96 | } 97 | } 98 | n = 2063512844981574047LL; 99 | while(cin >> n){ 100 | dprint(n); 101 | if(rabin (n)) 102 | cout << n << " es primo.\n"; 103 | else{ 104 | ll ans = rho (n); 105 | if (ans > n / ans) ans = n / ans; 106 | printf ("%lld = %lld * %lld\n", n, ans, n / ans); 107 | } 108 | } 109 | return 0; 110 | } 111 | -------------------------------------------------------------------------------- /math/polinomio.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cerr << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(auto it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | typedef long long ll; 13 | typedef pair ii; 14 | typedef int tipo; 15 | 16 | struct poly { 17 | vector c;//guarda los coeficientes del polinomio 18 | poly(const vector &c): c(c) {} 19 | poly() {} 20 | bool isnull() {return c.empty();} 21 | poly operator+(const poly &o) const { 22 | int m = sz(c), n = sz(o.c); 23 | vector res(max(m,n)); 24 | forn(i, m) res[i] += c[i]; 25 | forn(i, n) res[i] += o.c[i]; 26 | return poly(res); } 27 | poly operator*(const tipo cons) const { 28 | vector res(sz(c)); 29 | forn(i, sz(c)) res[i]=c[i]*cons; 30 | return poly(res); } 31 | poly operator*(const poly &o) const { 32 | int m = sz(c), n = sz(o.c); 33 | vector res(m+n-1); 34 | forn(i, m) forn(j, n) res[i+j]+=c[i]*o.c[j]; 35 | return poly(res); } 36 | tipo eval(tipo v) { 37 | tipo sum = 0; 38 | dforn(i, sz(c)) sum=sum*v + c[i]; 39 | return sum; } 40 | //poly contains only a vector c (the coeficients) 41 | //the following function generates the roots of the polynomial 42 | //it can be easily modified to return float roots 43 | set roots(){ 44 | set roots; 45 | tipo a0 = abs(c[0]), an = abs(c[sz(c)-1]); 46 | vector ps,qs; 47 | forr(p,1,sqrt(a0)+1) if (a0%p==0) ps.pb(p),ps.pb(a0/p); 48 | forr(q,1,sqrt(an)+1) if (an%q==0) qs.pb(q),qs.pb(an/q); 49 | forall(pt,ps) 50 | forall(qt,qs) if ( (*pt) % (*qt)==0 ) { 51 | tipo root = abs((*pt) / (*qt)); 52 | if (eval(root)==0) roots.insert(root); 53 | } 54 | return roots; } 55 | }; 56 | pair ruffini(const poly p, tipo r) { 57 | int n = sz(p.c) - 1 ; 58 | vector b(n); 59 | b[n-1] = p.c[n]; 60 | dforn(k,n-1) b[k] = p.c[k+1] + r*b[k+1]; 61 | tipo resto = p.c[0] + r*b[0]; 62 | poly result(b); 63 | return make_pair(result,resto); 64 | } 65 | poly interpolate(const vector& x,const vector& y) { 66 | poly A; A.c.pb(1); 67 | forn(i,sz(x)) { poly aux; aux.c.pb(-x[i]), aux.c.pb(1), A = A * aux; } 68 | poly S; S.c.pb(0); 69 | forn(i,sz(x)) { poly Li; 70 | Li = ruffini(A,x[i]).fst; 71 | Li = Li * (1.0 / Li.eval(x[i])); // here put a multiple of the coefficients instead of 1.0 to avoid using double 72 | S = S + Li * y[i]; } 73 | return S; 74 | } 75 | 76 | int main(){ 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /estructuras/convexhull.trick.dyn.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cout << #v"=" << v << endl 4 | #define forr(i, a, b) for(int i=a; i<(b); i++) 5 | #define forn(i, n) forr(i, 0, n) 6 | #define forall(it, v) for(auto it=v.begin(); it!=v.end(); ++it) 7 | #define sz(c) ((int)c.size()) 8 | #define zero(v) memset(v, 0, sizeof(v)) 9 | #define pb push_back 10 | #define fst first 11 | #define snd second 12 | typedef long long ll; 13 | typedef pair ii; 14 | #define EPS 1e-9 15 | #define tipo int 16 | 17 | const ll is_query = -(1LL<<62); 18 | struct Line { 19 | ll m, b; 20 | mutable multiset::iterator it; 21 | const Line *succ(multiset::iterator it) const; 22 | bool operator<(const Line& rhs) const { 23 | if (rhs.b != is_query) return m < rhs.m; 24 | const Line *s=succ(it); 25 | if(!s) return 0; 26 | ll x = rhs.m; 27 | return b - s->b < (s->m - m) * x; 28 | } 29 | }; 30 | struct HullDynamic : public multiset{ // will maintain upper hull for maximum 31 | bool bad(iterator y) { 32 | iterator z = next(y); 33 | if (y == begin()) { 34 | if (z == end()) return 0; 35 | return y->m == z->m && y->b <= z->b; 36 | } 37 | iterator x = prev(y); 38 | if (z == end()) return y->m == x->m && y->b <= x->b; 39 | return (x->b - y->b)*(z->m - y->m) >= (y->b - z->b)*(y->m - x->m); 40 | } 41 | iterator next(iterator y){return ++y;} 42 | iterator prev(iterator y){return --y;} 43 | void insert_line(ll m, ll b) { 44 | iterator y = insert((Line) { m, b }); 45 | y->it=y; 46 | if (bad(y)) { erase(y); return; } 47 | while (next(y) != end() && bad(next(y))) erase(next(y)); 48 | while (y != begin() && bad(prev(y))) erase(prev(y)); 49 | } 50 | ll eval(ll x) { 51 | Line l = *lower_bound((Line) { x, is_query }); 52 | return l.m * x + l.b; 53 | } 54 | }h; 55 | const Line *Line::succ(multiset::iterator it) const{ 56 | return (++it==h.end()? NULL : &*it);} 57 | 58 | //PROBLEMA F ACMICPC WORLD FINALS 2011 59 | struct machine{ 60 | ll d; 61 | ll p; 62 | ll r; 63 | ll g; 64 | } m[100010]; 65 | 66 | bool cmp (machine a, machine b){ 67 | return a.d < b.d; 68 | } 69 | int main(){ 70 | //~ freopen("f.in", "r", stdin); 71 | ll n, c,d, t = 1; 72 | while(cin >> n >> c >> d, n){ 73 | h=HullDynamic(); 74 | forn (i,n) 75 | cin >> m[i].d >> m[i].p >> m[i].r >> m[i].g; 76 | sort (m, m+n, cmp); 77 | 78 | 79 | h.insert_line(0,c); 80 | forn (i,n){ 81 | ll money = h.eval(m[i].d); 82 | if (m[i].p <= money) 83 | h.insert_line (m[i].g, money - m[i].p + m[i].r - m[i].g * (m[i].d + 1)); 84 | } 85 | 86 | cout << "Case " << t++ << ": " << h.eval (d+1) << endl; 87 | 88 | } 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /math/func.primos.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cerr << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(auto it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | typedef long long ll; 14 | typedef pair ii; 15 | 16 | #define MAXP 100000 //no necesariamente primo 17 | int criba[MAXP+1]; 18 | void crearcriba(){ 19 | int w[] = {4,2,4,2,4,6,2,6}; 20 | for(int p=25;p<=MAXP;p+=10) criba[p]=5; 21 | for(int p=9;p<=MAXP;p+=6) criba[p]=3; 22 | for(int p=4;p<=MAXP;p+=2) criba[p]=2; 23 | for(int p=7,cur=0;p*p<=MAXP;p+=w[cur++&7]) if (!criba[p]) 24 | for(int j=p*p;j<=MAXP;j+=(p<<1)) if(!criba[j]) criba[j]=p; 25 | } 26 | 27 | vector primos; 28 | void buscarprimos(){ 29 | crearcriba(); 30 | forr (i,2,MAXP+1) if (!criba[i]) primos.push_back(i); 31 | } 32 | 33 | //factoriza bien numeros hasta MAXP^2 34 | map fact(ll n){ //O (cant primos) 35 | map ret; 36 | forall(p, primos){ 37 | while(!(n%*p)){ 38 | ret[*p]++;//divisor found 39 | n/=*p; 40 | } 41 | } 42 | if(n>1) ret[n]++; 43 | return ret; 44 | } 45 | //factoriza bien numeros hasta MAXP 46 | map fact2(ll n){ //O (lg n) 47 | map ret; 48 | while (criba[n]){ 49 | ret[criba[n]]++; 50 | n/=criba[n]; 51 | } 52 | if(n>1) ret[n]++; 53 | return ret; 54 | } 55 | //Usar asi: divisores(fac, divs, fac.begin()); NO ESTA ORDENADO 56 | void divisores(const map &f, vector &divs, map::iterator it, ll n=1){ 57 | if(it==f.begin()) divs.clear(); 58 | if(it==f.end()) { divs.pb(n); return; } 59 | ll p=it->fst, k=it->snd; ++it; 60 | forn(_, k+1) divisores(f, divs, it, n), n*=p; 61 | } 62 | ll sumDiv (ll n){ 63 | ll rta = 1; 64 | map f=fact(n); 65 | forall(it, f) { 66 | ll pot = 1, aux = 0; 67 | forn(i, it->snd+1) aux += pot, pot *= it->fst; 68 | rta*=aux; 69 | } 70 | return rta; 71 | } 72 | ll eulerPhi (ll n){ // con criba: O(lg n) 73 | ll rta = n; 74 | map f=fact(n); 75 | forall(it, f) rta -= rta / it->first; 76 | return rta; 77 | } 78 | ll eulerPhi2 (ll n){ // O (sqrt n) 79 | ll r = n; 80 | forr (i,2,n+1){ 81 | if ((ll)i*i > n) break; 82 | if (n % i == 0){ 83 | while (n%i == 0) n/=i; 84 | r -= r/i; } 85 | } 86 | if (n != 1) r-= r/n; 87 | return r; 88 | } 89 | 90 | int main() { 91 | buscarprimos(); 92 | forr (x,1, 500000){ 93 | cout << "x = " << x << endl; 94 | cout << "Numero de factores primos: " << numPrimeFactors(x) << endl; 95 | cout << "Numero de distintos factores primos: " << numDiffPrimeFactors(x) << endl; 96 | cout << "Suma de factores primos: " << sumPrimeFactors(x) << endl; 97 | cout << "Numero de divisores: " << numDiv(x) << endl; 98 | cout << "Suma de divisores: " << sumDiv(x) << endl; 99 | cout << "Phi de Euler: " << eulerPhi(x) << endl; 100 | } 101 | return 0; 102 | } 103 | 104 | -------------------------------------------------------------------------------- /grafos/centroid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cerr << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | typedef long long ll; 14 | typedef pair ii; 15 | const int MAXN=100100; 16 | 17 | int n; 18 | vector G[MAXN]; 19 | bool taken[MAXN];//poner todos en FALSE al principio!! 20 | int padre[MAXN];//padre de cada nodo en el centroid tree 21 | 22 | int szt[MAXN]; 23 | void calcsz(int v, int p) { 24 | szt[v] = 1; 25 | forall(it,G[v]) if (*it!=p && !taken[*it]) 26 | calcsz(*it,v), szt[v]+=szt[*it]; 27 | } 28 | void centroid(int v=0, int f=-1, int lvl=0, int tam=-1) {//O(nlogn) 29 | if(tam==-1) calcsz(v, -1), tam=szt[v]; 30 | forall(it, G[v]) if(!taken[*it] && szt[*it]>=tam/2) 31 | {szt[v]=0; centroid(*it, f, lvl, tam); return;} 32 | taken[v]=true; 33 | padre[v]=f; 34 | forall(it, G[v]) if(!taken[*it]) 35 | centroid(*it, v, lvl+1, -1); 36 | } 37 | 38 | 39 | //f[v][k] holds the 2^k father of v 40 | //L[v] holds the level of v 41 | int f[MAXN][20], L[MAXN]; 42 | //call before build: 43 | void dfs(int v, int fa=-1, int lvl=0){//generate required data 44 | f[v][0]=fa, L[v]=lvl; 45 | forall(it, G[v])if(*it!=fa) 46 | dfs(*it, v, lvl+1); 47 | } 48 | void build(){//f[i][0] must be filled previously, O(nlgn) 49 | forn(k, 20-1) forn(i, n) f[i][k+1]=f[f[i][k]][k];} 50 | 51 | #define lg(x) (31-__builtin_clz(x))//=floor(log2(x)) 52 | 53 | int climb(int a, int d){//O(lgn) 54 | if(!d) return a; 55 | dforn(i, lg(L[a])+1) 56 | if(1<> n >> queris){ 90 | zero(G); 91 | zero(taken); 92 | forn(i, n-1){ 93 | int a,b; cin >> a >> b; a--, b--; 94 | G[a].pb(b), G[b].pb(a); 95 | } 96 | centroid(); 97 | dfs(0); 98 | build(); 99 | forn(i, n) dstsub[i]=1e9; 100 | update(0, 0); 101 | while(queris--){ 102 | int t,v; 103 | cin>> t >> v; v--; 104 | if(t==1) update(v, v); 105 | else cout << query(v, v) << endl; 106 | } 107 | } 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /estructuras/treap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cerr << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | typedef long long ll; 14 | typedef pair ii; 15 | 16 | typedef int Key; 17 | typedef struct node *pnode; 18 | struct node{ 19 | Key key; 20 | int prior, size; 21 | pnode l,r; 22 | node(Key key=0): key(key), prior(rand()), size(1), l(0), r(0) {} 23 | }; 24 | static int size(pnode p) { return p ? p->size : 0; } 25 | void push(pnode p) { 26 | // modificar y propagar el dirty a los hijos aca(para lazy) 27 | } 28 | // Update function and size from children's Value 29 | void pull(pnode p) {//recalcular valor del nodo aca (para rmq) 30 | p->size = 1 + size(p->l) + size(p->r); 31 | } 32 | //junta dos arreglos 33 | pnode merge(pnode l, pnode r) { 34 | if (!l || !r) return l ? l : r; 35 | push(l), push(r); 36 | pnode t; 37 | if (l->prior < r->prior) l->r=merge(l->r, r), t = l; 38 | else r->l=merge(l, r->l), t = r; 39 | pull(t); 40 | return t; 41 | } 42 | //parte el arreglo en dos, lkey) split(t->l, key, l, t->l), r = t; 47 | else split(t->r, key, t->r, r), l = t; 48 | pull(t); 49 | } 50 | 51 | void erase(pnode &t, Key key) { 52 | if (!t) return; 53 | push(t); 54 | if (key == t->key) t=merge(t->l, t->r); 55 | else if (key < t->key) erase(t->l, key); 56 | else erase(t->r, key); 57 | if(t) pull(t); 58 | } 59 | 60 | ostream& operator<<(ostream &out, const pnode &t) { 61 | if(!t) return out; 62 | return out << t->l << t->key << ' ' << t->r; 63 | } 64 | pnode find(pnode t, Key key) { 65 | if (!t) return 0; 66 | if (key == t->key) return t; 67 | if (key < t->key) return find(t->l, key); 68 | return find(t->r, key); 69 | } 70 | struct treap { 71 | pnode root; 72 | treap(pnode root=0): root(root) {} 73 | int size() { return ::size(root); } 74 | void insert(Key key) { 75 | pnode t1, t2; split(root, key, t1, t2); 76 | t1=::merge(t1,new node(key)); 77 | root=::merge(t1,t2); 78 | } 79 | void erase(Key key1, Key key2) { 80 | pnode t1,t2,t3; 81 | split(root,key1,t1,t2); 82 | split(t2,key2, t2, t3); 83 | root=merge(t1,t3); 84 | } 85 | void erase(Key key) {::erase(root, key);} 86 | pnode find(Key key) { return ::find(root, key); } 87 | Key &operator[](int pos){return find(pos)->key;}//ojito 88 | }; 89 | treap merge(treap a, treap b) {return treap(merge(a.root, b.root));} 90 | 91 | 92 | 93 | int main(){ 94 | treap t; 95 | int x; 96 | while(cin >> x) { 97 | if (x == 0) break; 98 | else if (x > 0) t.insert(x); 99 | else{ 100 | x = -x; 101 | t.erase(x); 102 | } 103 | cout << t.root << endl; 104 | } 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /string/corasick.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | #define forn(i,n) for(int i=0; iidhoja>=0) linkhoja->report(p); } 53 | void matching(const string &s, int p=0){ 54 | report(p); if(pmatching(s, p+1); } 55 | }cora; 56 | 57 | void ejemplo(){ 58 | cora=corasick();//clear 59 | cora.insert("ho", 1); 60 | cora.insert("hoho", 2); 61 | cora.insert("hola", 3); 62 | cora.matching("hohohola"); 63 | } 64 | 65 | // Codigo para: http://codeforces.com/problemset/problem/963/D 66 | // IMPORTANTE para testear prob. reemplazar 51 por esta linea en report: 67 | // if(idhoja>=0) found(idhoja, p-szhoja); 68 | // y comentar/descomentar 104/105 respectivamente. 69 | const int MAXN=1e5+100; 70 | string s; 71 | int n; 72 | int ks[MAXN]; 73 | int szq[MAXN]; 74 | 75 | vector matches[MAXN]; 76 | void found(int id, int p){ 77 | matches[id].push_back(p); 78 | } 79 | 80 | void solve_prob(){ 81 | while(cin >> s >> n){ 82 | cora=corasick(); 83 | zero(matches); 84 | forn(i, n){ 85 | string u; cin >> ks[i] >> u; 86 | szq[i]=sz(u); 87 | cora.insert(u, i); 88 | } 89 | cora.matching(s); 90 | forn(i, n){ 91 | if(sz(matches[i]) 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | #define dprint(v) cerr << #v"=" << v << endl //;) 10 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 11 | #define forn(i,n) forr(i,0,n) 12 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 13 | #define forall(it,v) for(typeof(v.begin()) it=v.begin();it!=v.end();++it) 14 | #define sz(c) ((int)c.size()) 15 | #define zero(v) memset(v, 0, sizeof(v)) 16 | #define fst first 17 | #define snd second 18 | 19 | #define pb push_back 20 | #define INF 1e9 21 | typedef long long ll; 22 | typedef pair ii; 23 | 24 | const int maxnodes = 2200; 25 | int nodes, src, dest; 26 | int dist[maxnodes], q[maxnodes], work[maxnodes]; 27 | 28 | struct Edge { 29 | int to, rev; 30 | ll f, cap; 31 | Edge(int to, int rev, ll f, ll cap) : to(to), rev(rev), f(f), cap(cap) {} 32 | }; 33 | 34 | vector g[maxnodes]; 35 | 36 | // Adds bidirectional edge 37 | void addEdge(int s, int t, ll cap){ 38 | Edge a = Edge(t, g[t].size(), 0, cap); 39 | Edge b = Edge(s, g[s].size(), 0, 0); 40 | g[s].push_back(a); 41 | g[t].push_back(b); 42 | } 43 | 44 | bool dinic_bfs() { 45 | fill(dist, dist + nodes, -1); 46 | dist[src] = 0; 47 | int qt = 0; 48 | q[qt++] = src; 49 | for (int qh = 0; qh < qt; qh++) { 50 | int u = q[qh]; 51 | for (int j = 0; j < (int) g[u].size(); j++) { 52 | Edge &e = g[u][j]; 53 | int v = e.to; 54 | if (dist[v] < 0 && e.f < e.cap) { 55 | dist[v] = dist[u] + 1; 56 | q[qt++] = v; 57 | } 58 | } 59 | } 60 | return dist[dest] >= 0; 61 | } 62 | 63 | ll dinic_dfs(int u, ll f) { 64 | if (u == dest) 65 | return f; 66 | for (int &i = work[u]; i < (int) g[u].size(); i++) { 67 | Edge &e = g[u][i]; 68 | if (e.cap <= e.f) continue; 69 | int v = e.to; 70 | if (dist[v] == dist[u] + 1) { 71 | ll df = dinic_dfs(v, min(f, e.cap - e.f)); 72 | if (df > 0) { 73 | e.f += df; 74 | g[v][e.rev].f -= df; 75 | return df; 76 | } 77 | } 78 | } 79 | return 0; 80 | } 81 | 82 | ll maxFlow(int _src, int _dest) { 83 | src = _src; 84 | dest = _dest; 85 | ll result = 0; 86 | while (dinic_bfs()) { 87 | fill(work, work + nodes, 0); 88 | while (ll delta = dinic_dfs(src, INF)) 89 | result += delta; 90 | } 91 | return result; 92 | } 93 | 94 | void cleanDinic() { 95 | forn(i,nodes) g[i].clear(); 96 | } 97 | 98 | // asume que el dinic YA ESTA tirado 99 | // asume que nodes-1 y nodes-2 son la fuente y destino 100 | int match[maxnodes]; // match[v]=u si u-v esta en el matching, -1 si v no esta matcheado 101 | int s[maxnodes]; // numero de la bfs del koning 102 | queue kq; 103 | // s[e]%2==1 o si e esta en V1 y s[e]==-1-> lo agarras 104 | void koning() {//O(n) 105 | forn(v,nodes-2) s[v] = match[v] = -1; 106 | forn(v,nodes-2) forall(it,g[v]) if (it->to < nodes-2 && it->f>0) 107 | { match[v]=it->to; match[it->to]=v;} 108 | forn(v,nodes-2) if (match[v]==-1) {s[v]=0;kq.push(v);} 109 | while(!kq.empty()) { 110 | int e = kq.front(); kq.pop(); 111 | if (s[e]%2==1) { 112 | s[match[e]] = s[e]+1; 113 | kq.push(match[e]); 114 | } else { 115 | 116 | forall(it,g[e]) if (it->to < nodes-2 && s[it->to]==-1) { 117 | s[it->to] = s[e]+1; 118 | kq.push(it->to); 119 | } 120 | } 121 | } 122 | } 123 | 124 | 125 | int main() { 126 | return 0; 127 | } 128 | -------------------------------------------------------------------------------- /grafos/dynamic.conectivity.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cerr << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(auto it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | #define mkp make_pair 14 | typedef long long ll; 15 | typedef pair ii; 16 | 17 | struct UnionFind { 18 | int n, comp; 19 | vector pre,si,c; 20 | UnionFind(int n=0):n(n), comp(n), pre(n), si(n, 1) { 21 | forn(i,n) pre[i] = i; } 22 | int find(int u){return u==pre[u]?u:find(pre[u]);} 23 | bool merge(int u, int v) { 24 | if((u=find(u))==(v=find(v))) return false; 25 | if(si[u]snap){ 32 | int v = c.back(); c.pop_back(); 33 | si[pre[v]] -= si[v], pre[v] = v, comp++; 34 | } 35 | } 36 | }; 37 | enum {ADD,DEL,QUERY}; 38 | struct Query {int type,u,v;}; 39 | struct DynCon { 40 | vector q; 41 | UnionFind dsu; 42 | vector match,res; 43 | map last;//se puede no usar cuando hay identificador para cada arista (mejora poco) 44 | DynCon(int n=0):dsu(n){} 45 | void add(int u, int v) { 46 | if(u>v) swap(u,v); 47 | q.pb((Query){ADD, u, v}), match.pb(-1); 48 | last[ii(u,v)] = sz(q)-1; 49 | } 50 | void remove(int u, int v) { 51 | if(u>v) swap(u,v); 52 | q.pb((Query){DEL, u, v}); 53 | int prev = last[ii(u,v)]; 54 | match[prev] = sz(q)-1; 55 | match.pb(prev); 56 | } 57 | void query() {//podria pasarle un puntero donde guardar la respuesta 58 | q.pb((Query){QUERY, -1, -1}), match.pb(-1);} 59 | void process() { 60 | forn(i,sz(q)) if (q[i].type == ADD && match[i] == -1) match[i] = sz(q); 61 | go(0,sz(q)); 62 | } 63 | void go(int l, int r) { 64 | if(l+1==r){ 65 | if (q[l].type == QUERY)//Aqui responder la query usando el dsu! 66 | res.pb(dsu.comp);//aqui query=cantidad de componentes conexas 67 | return; 68 | } 69 | int s=dsu.snap(), m = (l+r) / 2; 70 | forr(i,m,r) if(match[i]!=-1 && match[i]=r) dsu.merge(q[i].u, q[i].v); 75 | go(m,r); 76 | dsu.rollback(s); 77 | } 78 | }dc; 79 | 80 | // Problema ejemplo: http://codeforces.com/gym/100551/problem/A 81 | 82 | int n,k; 83 | 84 | int main() { 85 | //~ freopen("in", "r", stdin); 86 | freopen("connect.in", "r", stdin); 87 | freopen("connect.out", "w", stdout); 88 | ios::sync_with_stdio(0); 89 | while(cin >> n >> k){ 90 | dc=DynCon(n); 91 | forn(_,k) { string ord; cin >> ord; 92 | if (ord=="?") { 93 | dc.query(); 94 | } else if (ord=="+") { int a,b; cin>>a>>b; a--;b--; 95 | dc.add(a,b); 96 | } else if (ord=="-") { int a,b; cin>>a>>b; a--;b--; 97 | dc.remove(a,b); 98 | } else assert(false); 99 | } 100 | if(!k) continue;//k==0 WTF 101 | dc.process(); 102 | forn(i,sz(dc.res)) cout << dc.res[i] << endl; 103 | } 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /estructuras/bigint.cpp: -------------------------------------------------------------------------------- 1 | #define BASEXP 6 2 | #define BASE 1000000 3 | #define LMAX 1000 4 | struct bint{ 5 | int l; 6 | ll n[LMAX]; 7 | bint(ll x=0){ 8 | l=1; 9 | forn(i, LMAX){ 10 | if (x) l=i+1; 11 | n[i]=x%BASE; 12 | x/=BASE; 13 | 14 | } 15 | } 16 | bint(string x){ 17 | l=(x.size()-1)/BASEXP+1; 18 | fill(n, n+LMAX, 0); 19 | ll r=1; 20 | forn(i, sz(x)){ 21 | n[i / BASEXP] += r * (x[x.size()-1-i]-'0'); 22 | r*=10; if(r==BASE)r=1; 23 | } 24 | } 25 | void out(){ 26 | cout << n[l-1]; 27 | dforn(i, l-1) printf("%6.6llu", n[i]);//6=BASEXP! 28 | } 29 | void invar(){ 30 | fill(n+l, n+LMAX, 0); 31 | while(l>1 && !n[l-1]) l--; 32 | } 33 | }; 34 | bint operator+(const bint&a, const bint&b){ 35 | bint c; 36 | c.l = max(a.l, b.l); 37 | ll q = 0; 38 | forn(i, c.l) q += a.n[i]+b.n[i], c.n[i]=q %BASE, q/=BASE; 39 | if(q) c.n[c.l++] = q; 40 | c.invar(); 41 | return c; 42 | } 43 | pair lresta(const bint& a, const bint& b) // c = a - b 44 | { 45 | bint c; 46 | c.l = max(a.l, b.l); 47 | ll q = 0; 48 | forn(i, c.l) q += a.n[i]-b.n[i], c.n[i]=(q+BASE) %BASE, q=(q+BASE)/BASE-1; 49 | c.invar(); 50 | return make_pair(c, !q); 51 | } 52 | bint& operator-= (bint& a, const bint& b){return a=lresta(a, b).first;} 53 | bint operator- (const bint&a, const bint&b){return lresta(a, b).first;} 54 | bool operator< (const bint&a, const bint&b){return !lresta(a, b).second;} 55 | bool operator<= (const bint&a, const bint&b){return lresta(b, a).second;} 56 | bool operator==(const bint&a, const bint&b){return a <= b && b <= a;} 57 | bint operator*(const bint&a, ll b){ 58 | bint c; 59 | ll q = 0; 60 | forn(i, a.l) q += a.n[i]*b, c.n[i] = q %BASE, q/=BASE; 61 | c.l = a.l; 62 | while(q) c.n[c.l++] = q %BASE, q/=BASE; 63 | c.invar(); 64 | return c; 65 | } 66 | bint operator*(const bint&a, const bint&b){ 67 | bint c; 68 | c.l = a.l+b.l; 69 | fill(c.n, c.n+b.l, 0); 70 | forn(i, a.l){ 71 | ll q = 0; 72 | forn(j, b.l) q += a.n[i]*b.n[j]+c.n[i+j], c.n[i+j] = q %BASE, q/=BASE; 73 | c.n[i+b.l] = q; 74 | } 75 | c.invar(); 76 | return c; 77 | } 78 | pair ldiv(const bint& a, ll b){// c = a / b ; rm = a % b 79 | bint c; 80 | ll rm = 0; 81 | dforn(i, a.l){ 82 | rm = rm * BASE + a.n[i]; 83 | c.n[i] = rm / b; 84 | rm %= b; 85 | } 86 | c.l = a.l; 87 | c.invar(); 88 | return make_pair(c, rm); 89 | } 90 | bint operator/(const bint&a, ll b){return ldiv(a, b).first;} 91 | ll operator%(const bint&a, ll b){return ldiv(a, b).second;} 92 | pair ldiv(const bint& a, const bint& b){ 93 | bint c; 94 | bint rm = 0; 95 | dforn(i, a.l){ 96 | if (rm.l==1 && !rm.n[0]) 97 | rm.n[0] = a.n[i]; 98 | else{ 99 | dforn(j, rm.l) rm.n[j+1] = rm.n[j]; 100 | rm.n[0] = a.n[i]; 101 | rm.l++; 102 | } 103 | ll q = rm.n[b.l] * BASE + rm.n[b.l-1]; 104 | ll u = q / (b.n[b.l-1] + 1); 105 | ll v = q / b.n[b.l-1] + 1; 106 | while (u < v-1){ 107 | ll m = (u+v)/2; 108 | if (b*m <= rm) u = m; 109 | else v = m; 110 | } 111 | c.n[i]=u; 112 | rm-=b*u; 113 | } 114 | c.l=a.l; 115 | c.invar(); 116 | return make_pair(c, rm); 117 | } 118 | bint operator/(const bint&a, const bint&b){return ldiv(a, b).first;} 119 | bint operator%(const bint&a, const bint&b){return ldiv(a, b).second;} 120 | -------------------------------------------------------------------------------- /estructuras/convexhull.trick.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | #define dprint(v) cerr << #v"=" << v << endl //;) 5 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 6 | #define forn(i,n) forr(i,0,n) 7 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 8 | #define forall(it,v) for(auto it=v.begin();it!=v.end();++it) 9 | #define sz(c) ((int)c.size()) 10 | #define zero(v) memset(v, 0, sizeof(v)) 11 | #define pb push_back 12 | #define fst first 13 | #define snd second 14 | typedef long long ll; 15 | typedef pair ii; 16 | typedef ll tipo; 17 | 18 | struct Line{tipo m,h;}; 19 | tipo inter(Line a, Line b){ 20 | tipo x=b.h-a.h, y=a.m-b.m; 21 | return x/y+(x%y?!((x>0)^(y>0)):0);//==ceil(x/y) 22 | } 23 | struct CHT { 24 | vector c; 25 | bool mx; 26 | int pos; 27 | CHT(bool mx=0):mx(mx),pos(0){}//mx=1 si las query devuelven el max 28 | inline Line acc(int i){return c[c[0].m>c.back().m? i : sz(c)-1-i];} 29 | inline bool irre(Line x, Line y, Line z){ 30 | return c[0].m>z.m? inter(y, z) <= inter(x, y) 31 | : inter(y, z) >= inter(x, y); 32 | } 33 | void add(tipo m, tipo h) {//O(1), los m tienen que entrar ordenados 34 | if(mx) m*=-1, h*=-1; 35 | Line l=(Line){m, h}; 36 | if(sz(c) && m==c.back().m) { l.h=min(h, c.back().h), c.pop_back(); if(pos) pos--; } 37 | while(sz(c)>=2 && irre(c[sz(c)-2], c[sz(c)-1], l)) { c.pop_back(); if(pos) pos--; } 38 | c.pb(l); 39 | } 40 | inline bool fbin(tipo x, int m) {return inter(acc(m), acc(m+1))>x;} 41 | tipo eval(tipo x){ 42 | int n = sz(c); 43 | //query con x no ordenados O(lgn) 44 | int a=-1, b=n-1; 45 | while(b-a>1) { int m = (a+b)/2; 46 | if(fbin(x, m)) b=m; 47 | else a=m; 48 | } 49 | return (acc(b).m*x+acc(b).h)*(mx?-1:1); 50 | //query O(1) 51 | while(pos>0 && fbin(x, pos-1)) pos--; 52 | while(pos c; 61 | bool mx; 62 | CHTBruto(bool mx=0):mx(mx){}//mx=si las query devuelven el max o el min 63 | void add(tipo m, tipo h) { 64 | Line l=(Line){m, h}; 65 | c.pb(l); 66 | } 67 | tipo eval(tipo x){ 68 | tipo r=c[0].m*x+c[0].h; 69 | forn(i, sz(c)) if(mx) r=max(r, c[i].m*x+c[i].h); 70 | else r=min(r, c[i].m*x+c[i].h); 71 | return r; 72 | } 73 | } chb; 74 | 75 | #define RND(a, b) (rand()%((b)-(a)+1)+(a)) 76 | #define MAXM 10000 77 | #define MINIT RND(-1000, 1000) 78 | #define MSTEP RND(0, 10) 79 | 80 | #define HVAL RND(-1000, 1000) 81 | #define XVAL RND(-1000, 1000) 82 | #define MAXSZ 1000000 83 | 84 | int main() { 85 | tipo m,h,x; 86 | int t; 87 | int dir; 88 | int seed=time(NULL); 89 | srand(seed); 90 | for(int tc=0; ; tc++){ reset: 91 | t=0; 92 | t=rand()%2; 93 | dir=-1; 94 | dir=rand()%2?1:-1; 95 | m=MINIT; 96 | if(!m) m++; 97 | cout << "CLEAR, QUERY " << (t?"MAX":"MIN") << endl; 98 | ch=CHT(t), chb=CHTBruto(t); 99 | forn(_, 25){ 100 | m=m+dir*MSTEP; 101 | if(!m) m+=dir; 102 | if(m>MAXM) goto reset; 103 | h=HVAL; 104 | cout << "ADD " << m << ' ' << h << endl; 105 | ch.add(m, h); 106 | chb.add(m, h); 107 | } 108 | x=XVAL; 109 | tipo v=ch.eval(x); 110 | tipo b=chb.eval(x); 111 | cout << "QUERY " << x << ' ' << v << ' ' << b << endl; 112 | assert(v==b || !(dprint(seed))); 113 | } 114 | return 0; 115 | } 116 | -------------------------------------------------------------------------------- /preamble.margenes.chicos.tex: -------------------------------------------------------------------------------- 1 | \documentclass[10pt,landscape,twocolumn,a4paper,notitlepage]{article} 2 | \usepackage{hyperref} 3 | \usepackage[spanish, activeacute]{babel} 4 | \usepackage[utf8]{inputenc} 5 | \usepackage{fancyhdr} 6 | \usepackage{lastpage} 7 | \usepackage{listings} 8 | \usepackage{amssymb} 9 | \usepackage[usenames,dvipsnames]{color} 10 | \usepackage{graphicx} 11 | \usepackage{wrapfig} 12 | \usepackage{amsmath} 13 | \usepackage{makeidx} 14 | 15 | %%% Ocultar subsecciones del indice 16 | \hypersetup{bookmarksopen=true,bookmarksopenlevel=1} 17 | \setcounter{tocdepth}{1} 18 | 19 | %%% Espacio de los titulos 20 | \usepackage{titlesec} 21 | \titleformat{\section} {\normalfont\Large\bfseries\centering}{\thesection}{1em}{} 22 | \titleformat{\subsection} {\normalfont\large\bfseries\centering}{\thesubsection}{1em}{} 23 | \titlespacing*{\subsection}{0pt}{0pt}{0pt} % interespacio de las subsecciones 24 | 25 | %%% Margenes 26 | \setlength{\columnsep}{0.0in} % default=10pt 27 | \setlength{\columnseprule}{0.0pt} % default=0pt (no line) 28 | 29 | \addtolength{\textheight}{2.9in} 30 | \addtolength{\topmargin}{-1.2in} % ~ -0.5 del incremento anterior 31 | 32 | \addtolength{\textwidth}{1.8in} 33 | \addtolength{\oddsidemargin}{-0.9in} % -0.5 del incremento anterior 34 | 35 | \setlength{\headsep}{0.08in} 36 | \setlength{\parskip}{0in} 37 | \setlength{\headheight}{15pt} 38 | \setlength{\parindent}{0mm} 39 | 40 | %%% Encabezado y pie de pagina 41 | \pagestyle{fancy} 42 | \fancyhead[LO]{\textbf{\title}} 43 | \fancyhead[C]{\leftmark\ -\ \rightmark} 44 | \fancyhead[RO]{P\'agina \thepage\ de \pageref{LastPage}} 45 | \renewcommand{\headrulewidth}{0.4pt} 46 | \fancyfoot{} 47 | \definecolor{darkblue}{rgb}{0,0,0.4} 48 | %%% Configuracion de Listings 49 | \lstloadlanguages{C++} 50 | \lstnewenvironment{code} 51 | {%\lstset{ numbers=none, frame=lines, basicstyle=\small\ttfamily, }% 52 | \csname lst@SetFirstLabel\endcsname} 53 | {\csname lst@SaveFirstLabel\endcsname} 54 | \lstset{% general command to set parameter(s) 55 | language=C++, basicstyle=\small\ttfamily, keywordstyle=\slshape, 56 | emph=[1]{tipo,usa}, emphstyle={[1]\sffamily\bfseries}, 57 | morekeywords={tint,forn,forsn}, 58 | basewidth={0.47em,0.40em}, 59 | columns=fixed, fontadjust, resetmargins, xrightmargin=5pt, xleftmargin=15pt, 60 | flexiblecolumns=false, tabsize=2, breaklines, breakatwhitespace=false, extendedchars=true, 61 | numbers=left, numberstyle=\tiny, stepnumber=1, numbersep=9pt, 62 | frame=l, framesep=3pt, 63 | basicstyle=\ttfamily, 64 | keywordstyle=\color{darkblue}\ttfamily, 65 | stringstyle=\color{magenta}\ttfamily, 66 | commentstyle=\color{RedOrange}\ttfamily, 67 | morecomment=[l][\color{OliveGreen}]{\#} 68 | } 69 | 70 | \lstdefinestyle{C++}{ 71 | language=C++, basicstyle=\small\ttfamily, keywordstyle=\slshape, 72 | emph=[1]{tipo,usa,tipo2}, emphstyle={[1]\sffamily\bfseries}, 73 | morekeywords={tint,forn,forsn}, 74 | basewidth={0.47em,0.40em}, 75 | columns=fixed, fontadjust, resetmargins, xrightmargin=5pt, xleftmargin=15pt, 76 | flexiblecolumns=false, tabsize=2, breaklines, breakatwhitespace=false, extendedchars=true, 77 | numbers=left, numberstyle=\tiny, stepnumber=1, numbersep=9pt, 78 | frame=l, framesep=3pt, 79 | basicstyle=\ttfamily, 80 | keywordstyle=\color{darkblue}\ttfamily, 81 | stringstyle=\color{magenta}\ttfamily, 82 | commentstyle=\color{RedOrange}\ttfamily, 83 | morecomment=[l][\color{OliveGreen}]{\#} 84 | } 85 | 86 | %%% Macros 87 | \def\nbtitle#1{\begin{Large}\begin{center}\textbf{#1}\end{center}\end{Large}} 88 | \def\nbsection#1{\section{#1}} 89 | \def\nbsubsection#1{\subsection{#1}} 90 | \def\nbcoment#1{\begin{small}\textbf{#1}\end{small}} 91 | \newcommand{\comb}[2]{\left( \begin{array}{c} #1 \\ #2 \end{array}\right)} 92 | \def\complexity#1{\texorpdfstring{$\mathcal{O}(#1)$}{O(#1)}} 93 | \newcommand\cppfile[2][]{ 94 | \lstinputlisting[style=C++,linerange={#1}]{#2} 95 | } 96 | -------------------------------------------------------------------------------- /estructuras/treaparr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define dprint(v) cerr << #v"=" << v << endl //;) 4 | #define forr(i,a,b) for(int i=(a); i<(b); i++) 5 | #define forn(i,n) forr(i,0,n) 6 | #define dforn(i,n) for(int i=n-1; i>=0; i--) 7 | #define forall(it,v) for(auto it=v.begin();it!=v.end();++it) 8 | #define sz(c) ((int)c.size()) 9 | #define zero(v) memset(v, 0, sizeof(v)) 10 | #define pb push_back 11 | #define fst first 12 | #define snd second 13 | typedef long long ll; 14 | typedef pair ii; 15 | 16 | typedef ii Value;//ii(profundidad, nodo) 17 | typedef struct node *pnode; 18 | struct node{ 19 | Value val, mini; 20 | int dirty; 21 | int prior, size; 22 | pnode l,r,parent; 23 | node(Value val): val(val), mini(val), dirty(0), prior(rand()), size(1), l(0), r(0), parent(0) {} 24 | }; 25 | static int size(pnode p) { return p ? p->size : 0; } 26 | void push(pnode p) {//propagar dirty a los hijos(aca para lazy) 27 | p->val.fst+=p->dirty; 28 | p->mini.fst+=p->dirty; 29 | if(p->l) p->l->dirty+=p->dirty; 30 | if(p->r) p->r->dirty+=p->dirty; 31 | p->dirty=0; 32 | } 33 | static Value mini(pnode p) { return p ? push(p), p->mini : ii(1e9, -1); } 34 | // Update function and size from children's Value 35 | void pull(pnode p) {//recalcular valor del nodo aca (para rmq) 36 | p->size = 1 + size(p->l) + size(p->r); 37 | p->mini = min(min(p->val, mini(p->l)), mini(p->r));//operacion del rmq! 38 | p->parent=0; 39 | if(p->l) p->l->parent=p; 40 | if(p->r) p->r->parent=p; 41 | } 42 | //junta dos arreglos 43 | pnode merge(pnode l, pnode r) { 44 | if (!l || !r) return l ? l : r; 45 | push(l), push(r); 46 | pnode t; 47 | if (l->prior < r->prior) l->r=merge(l->r, r), t = l; 48 | else r->l=merge(l, r->l), t = r; 49 | pull(t); 50 | return t; 51 | } 52 | //parte el arreglo en dos, sz(l)==tam 53 | void split(pnode t, int tam, pnode &l, pnode &r) { 54 | if (!t) return void(l = r = 0); 55 | push(t); 56 | if (tam <= size(t->l)) split(t->l, tam, l, t->l), r = t; 57 | else split(t->r, tam - 1 - size(t->l), t->r, r), l = t; 58 | pull(t); 59 | } 60 | pnode at(pnode t, int pos) { 61 | if(!t) exit(1); 62 | push(t); 63 | if(pos == size(t->l)) return t; 64 | if(pos < size(t->l)) return at(t->l, pos); 65 | return at(t->r, pos - 1 - size(t->l)); 66 | } 67 | int getpos(pnode t){//inversa de at 68 | if(!t->parent) return size(t->l); 69 | if(t==t->parent->l) return getpos(t->parent)-size(t->r)-1; 70 | return getpos(t->parent)+size(t->l)+1; 71 | } 72 | void split(pnode t, int i, int j, pnode &l, pnode &m, pnode &r) { 73 | split(t, i, l, t), split(t, j-i, m, r);} 74 | Value get(pnode &p, int i, int j){//like rmq 75 | pnode l,m,r; 76 | split(p, i, j, l, m, r); 77 | Value ret=mini(m); 78 | p=merge(l, merge(m, r)); 79 | return ret; 80 | } 81 | void print(const pnode &t) {//for debugging 82 | if(!t) return; 83 | push(t); 84 | print(t->l); 85 | cout << t->val.fst << ' '; 86 | print(t->r); 87 | } 88 | 89 | //Sample program: C. LCA Online from Petrozavodsk Summer-2012. Petrozavodsk SU Contest 90 | //Available at http://opentrains.snarknews.info/~ejudge 91 | const int MAXN=300100; 92 | int n; 93 | pnode beg[MAXN], fin[MAXN]; 94 | pnode lista; 95 | vector G[MAXN]; 96 | void euler(int v, int L=0){ 97 | fin[v]=beg[v]=new node(ii(L, v)); 98 | lista=merge(lista, fin[v]); 99 | forall(it, G[v]){ 100 | euler(*it, L+1); 101 | fin[v]=new node(ii(L, v)); 102 | lista=merge(lista, fin[v]); 103 | } 104 | } 105 | 106 | int query(int u, int v){ 107 | int pu=getpos(beg[u]), pv=getpos(beg[v]); 108 | if(pu>pv) return query(v, u); 109 | pnode l,m,r; 110 | split(lista, pu, pv+1, l, m, r); 111 | int ret=mini(m).snd; 112 | lista=merge(merge(l, m),r); 113 | return ret; 114 | } 115 | 116 | void change(int u, int nuparent){ 117 | int b=getpos(beg[u]), e=getpos(fin[u]); 118 | int pnu=getpos(beg[nuparent]); 119 | int lv=get(lista, pnu, pnu+1).fst; 120 | pnode l,m,r; 121 | split(lista, b, e+1, l, m, r); 122 | m->dirty=-get(m, 0, 1).fst+lv+1; 123 | lista=merge(l, r); 124 | split(lista, getpos(fin[nuparent])+1, l, r); 125 | fin[nuparent]=new node(ii(lv, nuparent)); 126 | lista=merge(merge(l, m), merge(fin[nuparent], r)); 127 | } 128 | 129 | int main() { 130 | //~ freopen("f.in", "r", stdin); 131 | freopen("lca.in", "r", stdin); 132 | freopen("lca.out", "w", stdout); 133 | ios::sync_with_stdio(0); 134 | while(cin >> n){ 135 | zero(G); 136 | forn(i, n-1){ 137 | int x; cin >>x; x--; 138 | G[x].pb(i+1); 139 | } 140 | lista=0; 141 | euler(0); 142 | int m; cin >> m; 143 | while(m--){ 144 | char ty[10]; int u,v; 145 | cin >> ty >> u >> v; u--, v--; 146 | if(ty[0]=='Q') cout << query(u, v)+1 << endl; 147 | else change(u, v); 148 | } 149 | } 150 | return 0; 151 | } 152 | -------------------------------------------------------------------------------- /villeador.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.7 2 | # C Minify Copyright (C) 2015 Alexandre Baron 3 | # This program comes with ABSOLUTELY NO WARRANTY; for details read LICENSE. 4 | # This is free software, and you are welcome to redistribute it 5 | # under certain conditions; read LICENSE for details. 6 | 7 | import argparse 8 | import sys 9 | import re 10 | import os # SEEK_END etc. 11 | 12 | # Ops: ops that may be spaced out in the code but we can trim the whitespace before and after 13 | # Spaced ops are operators that we need to append with one trailing space because of their syntax (e.g. keywords). 14 | # NB: theses ops are the SUPPORTED ones and these lists may not be complete as per the Standard 15 | OPS = [ 16 | '+', '-', '*', '/', '%', '++', '--', 17 | '+=', '-=', '*=', '/=', '%=', '=', '==', '!=', 18 | '&&', '||', '!', '&', '|', '^', '<<', '>>', 19 | '<', '>', '<=', '>=', '<<=', '>>=', '&=', '|=', '^=', ',', 20 | '(', ')', '{', '}', ';', 'else', '?', ':' 21 | ] 22 | SPACED_OPS = ['else'] 23 | UNARY_OPS= ["+", "-", "&", "!", "*"] 24 | 25 | def remove_everything_between(subs1, subs2, line): 26 | regex = re.compile(subs1 + r'.*' + subs2) 27 | return regex.sub('', line) 28 | 29 | 30 | def remove_everything_before(subs, line): 31 | regex = re.compile(r'.*' + subs) 32 | return regex.sub('', line) 33 | 34 | 35 | def remove_everything_past(subs, line): 36 | regex = re.compile(subs + r'.*') 37 | return regex.sub('', line) 38 | 39 | 40 | def remove_multiline_comments(lines): 41 | start, end = '/*', '*/' 42 | escaped_start, escaped_end = '/\*', '\*/' 43 | in_comment = False 44 | newlines = [] 45 | for line in lines: 46 | if not in_comment: 47 | start_pos = line.find(start) 48 | if start_pos != -1: 49 | in_comment = True 50 | end_pos = line.find(end) 51 | # inline multiline comment 52 | if start_pos < end_pos: 53 | line = remove_everything_between(escaped_start, escaped_end, line) 54 | in_comment = False 55 | else: 56 | line = remove_everything_past(escaped_start, line) 57 | else: 58 | end_pos = line.find(end) 59 | if end_pos != -1: 60 | line = remove_everything_before(escaped_end, line) 61 | in_comment = False 62 | start_pos = line.find(start) 63 | # start of another comment on the same line 64 | if start_pos != -1: 65 | line = remove_everything_past(escaped_start, line) 66 | in_comment = True 67 | else: 68 | line = '' 69 | newlines.append(line) 70 | return newlines 71 | 72 | 73 | def remove_inline_comments(lines): 74 | return map(lambda x: remove_everything_past('//', x), lines) 75 | 76 | 77 | def minify_operator(op): 78 | """Returns a function applying a regex to strip away spaces on each side of an operator 79 | Makes a special escape for operators that could be mistaken for regex control characters.""" 80 | to_compile = " *{} *".format(re.escape(op)) 81 | regex = re.compile(to_compile) 82 | repl = op 83 | if op in SPACED_OPS: 84 | repl += " " 85 | return lambda string: regex.sub(repl, string) 86 | 87 | 88 | def show_stats(source_file, minified_text): 89 | # After "f.readlines", the file pointer is at file's end so tell() will return current file size. 90 | orig_size = source_file.tell() 91 | mini_size = len(minified_text) 92 | delta = orig_size - mini_size 93 | print( 94 | "Original: {0} characters, Minified: {1} characters, {2} removed ({3:.1f}%)" 95 | .format(orig_size, mini_size, delta, (float(delta) / float(orig_size)) * 100.0) 96 | ) 97 | 98 | 99 | def fix_spaced_ops(minified_txt): 100 | """This will walk the spaced ops list and search the text for all "[OP] {" sequences occurrences 101 | and replace them by "[OP]{" since there is no operator in the C syntax for which the spacing 102 | between the op and the '{' is mandatory. 103 | We do this because to manage spaced ops that may or may not be used with braces (e.g. "else"), 104 | we may have added unnecessary spaces (e.g. because the brace was on next line), 105 | so we can fix it here.""" 106 | for op in SPACED_OPS: 107 | pattern = "{} {{".format(op) # {{ for literal braces 108 | repl = "{}{{".format(op) 109 | minified_txt = re.sub(pattern, repl, minified_txt) 110 | return minified_txt 111 | 112 | 113 | def fix_unary_operators(lines): 114 | """Ops processing can have eliminated necessary space when using unary ops 115 | e.g. "#define ABC -1" becomes "#define ABC-1", because the unary '-' is being 116 | mistaken for a binary '-', so the space has been trimmed. 117 | We can fix this kind of thing here, but it pretty much highlights the limits of such 118 | a parser...""" 119 | regex_unary_ops = '[{}]'.format(''.join(UNARY_OPS)) 120 | regex_unary_ops = re.escape(regex_unary_ops) 121 | # Use capture groups to separate, e.g. in "#define MACROVALUE", "#define MACRO" from "VALUE" 122 | # pattern will detect problems like "#define FLUSH-2" 123 | # Format braces here -----------v 124 | pattern = "^(#[a-z]+ +[\w\d]+)([{}][\w\d]+)$".format(regex_unary_ops) 125 | # Simply add one more space between macro name and value 126 | repl = r'\1' + " " + r'\2' 127 | # Process each preprocessor line and modify it inplace as we need to keep order 128 | for (idx, line) in enumerate(lines): 129 | if line.startswith('#'): 130 | for op in UNARY_OPS: 131 | line = re.sub(pattern, repl, line) 132 | lines[idx] = line 133 | return lines 134 | 135 | 136 | def minify_source_file(args, filename): 137 | with open(filename) as f: 138 | if args.names is True: 139 | print("File {}:".format(source_file)) 140 | lines = f.readlines() 141 | if args.keep_newline is False: 142 | # Keep preprocessor lines (starting with #) 143 | lines = map(lambda x: x.replace(args.crlf, '') if not x.startswith('#') else x, lines) 144 | lines = map(lambda x: x.replace('\t', ' '), lines) 145 | # erase leading and trailing whitespace but do it BEFORE processing spaced ops! 146 | # and specify only spaces so it doesn't strip newlines 147 | lines = map(lambda x: x.strip(' '), lines) 148 | # for each operator: remove space on each side of the op, on every line. 149 | # Escape ops that could be regex control characters. 150 | for op in OPS: 151 | lines = map(minify_operator(op), lines) 152 | if args.keep_inline is False: 153 | lines = remove_inline_comments(lines) 154 | if args.keep_multiline is False: 155 | lines = remove_multiline_comments(lines) 156 | # Finally convert all remaining multispaces to a single space 157 | multi_spaces = re.compile(r'[ ]+ *') 158 | lines = map(lambda string: multi_spaces.sub(' ', string), lines) 159 | # Ops processing can have eliminated necessary space when using unary ops 160 | # e.g. "#define ABC -1" becomes "#define ABC-1", so we can fix it here 161 | lines = fix_unary_operators(lines) 162 | minified = ''.join(lines) 163 | # There is no syntactic requirement of an operator being spaced from a '{' in C so 164 | # if we added unnecessary space when processing spaced ops, we can fix it here 165 | minified = fix_spaced_ops(minified) 166 | print(minified) 167 | if args.stats is True: 168 | show_stats(f, minified) 169 | 170 | 171 | def get_args(): 172 | parser = argparse.ArgumentParser() 173 | parser.add_argument("files", nargs='+', help="Input files") 174 | parser.add_argument("-c", "--crlf", 175 | help="Use CRLF as newline control character (\r\n)", 176 | default='\n', 177 | action='store_const', const='\r\n') 178 | parser.add_argument("-n", "--names", 179 | help="Show name of processed files", 180 | action='store_true') 181 | parser.add_argument("-s", "--stats", 182 | help="Show statistics on minified version", 183 | action='store_true') 184 | parser.add_argument("-m", "--keep-multiline", 185 | help="Don't strip multiline comments (/* ... */)", 186 | action='store_true') 187 | parser.add_argument("-i", "--keep-inline", 188 | help="Do not strip inline comments (// ...)", 189 | action='store_true') 190 | parser.add_argument("-w", "--keep-newline", 191 | help="Keep newline control characters", 192 | action='store_true') 193 | args = parser.parse_args() 194 | return args 195 | 196 | 197 | def main(): 198 | args = get_args() 199 | for filename in args.files: 200 | minify_source_file(args, filename) 201 | 202 | if __name__ == "__main__": 203 | main() 204 | -------------------------------------------------------------------------------- /eldiegorecortado.tex: -------------------------------------------------------------------------------- 1 | % LaTeXar con : 2 | % pdflatex eldiego.tex 3 | %"The PDF file may contain up to 25 pages of reference material, single-sided, letter or A4 size, with text and illustrations readable by a person with correctable eyesight without magnification from a distance of 1/2 meter." 4 | \input{preamble.margenes.chicos.tex} 5 | \begin{document} 6 | \def\title{Caloventor en Dos - Universidad Nacional de Rosario} 7 | \section{algorithm}%%%%%%%%%%%%%%%%%%ALGORITHM%%%%%%%%%%%%%%%%%% 8 | \input{algorithm.tex} 9 | 10 | \section{Estructuras}%%%%%%%%%%%%%%%%%%ESTRUCTURAS%%%%%%%%%%%%%%%%%% 11 | \subsection{RMQ (static)} 12 | Dado un arreglo y una operacion asociativa \emph{idempotente}, get(i, j) opera sobre el rango [i, j). Restriccion: LVL $\ge$ ceil(logn); Usar [ ] para llenar arreglo y luego build(). 13 | \cppfile{estructuras/rmq.static.cpp} 14 | \subsection{RMQ (dynamic)} 15 | \cppfile{estructuras/rmq.dynamic.cpp} 16 | \subsection{RMQ (lazy)} 17 | \cppfile{estructuras/rmq.lazy.cpp} 18 | \subsection{RMQ (persistente)} 19 | \cppfile[23-53]{estructuras/rmq.persistent.cpp} 20 | \subsection{Fenwick Tree} 21 | \cppfile{estructuras/fenwick.cpp} 22 | \subsection{Union Find} 23 | \cppfile{grafos/union.find.cpp} 24 | \subsection{Disjoint Intervals} 25 | \cppfile{estructuras/disjoint.intervals.cpp} 26 | \subsection{RMQ (2D)} 27 | \cppfile{estructuras/rmq.2d.cpp} 28 | \subsection{Big Int} 29 | \cppfile{estructuras/bigint.villa.cpp} 30 | \subsection{HashTables} 31 | \cppfile[16-30]{hash.cpp} 32 | \subsection{Modnum} 33 | \cppfile{estructuras/mnum.cpp} 34 | \subsection{Treap para set} 35 | \cppfile[16-89]{estructuras/treap.cpp} 36 | \subsection{Treap para arreglo} 37 | \cppfile[17-87]{estructuras/treaparr.cpp} 38 | \subsection{Convex Hull Trick} 39 | \cppfile[18-55]{estructuras/convexhull.trick.cpp} 40 | \subsection{Convex Hull Trick (Dynamic)} 41 | \cppfile[17-56]{estructuras/convexhull.trick.dyn.cpp} 42 | %\subsection{Gain-Cost Set} 43 | %\cppfile[20-43]{estructuras/gain-cost.set.cpp} 44 | \subsection{Set con busq binaria} 45 | \cppfile[17-26]{estructuras/order.tree.cpp} 46 | 47 | 48 | \section{Algos}%%%%%%%%%%%%%%%%%%ALGORITMOS%%%%%%%%%%%%%%%%%%%%%%%%%% 49 | \subsection{Longest Increasing Subsecuence} 50 | \cppfile[14-42]{algos/lis.cpp} 51 | \subsection{Alpha-Beta prunning} 52 | \cppfile{algos/alphabeta.cpp} 53 | \subsection{Mo's algorithm} 54 | \cppfile{algos/mosalgorithm.cpp} 55 | 56 | 57 | \section{Strings}%%%%%%%%%%%%%%%%%%STRINGS%%%%%%%%%%%%%%%%%%%%%%%%%% 58 | \subsection{Manacher} 59 | \cppfile[18-37]{string/manacher.cpp} 60 | \subsection{KMP} 61 | \cppfile[21-38]{string/kmp.cpp} 62 | \subsection{Trie} 63 | \cppfile{string/trie.cpp} 64 | %\subsection{Suffix Array (corto, nlog2n)} 65 | %\cppfile[12-26]{string/suffix.array.short.cpp} 66 | \subsection{Suffix Array (largo, nlogn)} 67 | \cppfile[-34]{string/suffix.array.cpp} 68 | \subsection{String Matching With Suffix Array} 69 | \cppfile[37-58]{string/suffix.array.cpp} 70 | \subsection{LCP (Longest Common Prefix)} 71 | \cppfile[60-75]{string/suffix.array.cpp} 72 | \subsection{Corasick} 73 | \cppfile[16-55]{string/corasick.cpp} 74 | \subsection{Suffix Automaton} 75 | \cppfile[16-61]{string/suffix.automaton.cpp} 76 | \subsection{Z Function} 77 | \cppfile[17-27]{string/zfunction.cpp} 78 | 79 | 80 | \section{Geometria}%%%%%%%%%%%%%%%%%%GEOMETRIA%%%%%%%%%%%%%%%%%%%%%% 81 | \subsection{Punto} 82 | \cppfile[2-33]{geometria/pto.cpp} 83 | \subsection{Orden radial de puntos} 84 | \cppfile{geometria/orden.radial.cpp} 85 | \subsection{Line} 86 | \cppfile{geometria/line.cpp} 87 | \subsection{Segment} 88 | \cppfile{geometria/segm.cpp} 89 | %\subsection{Rectangle} 90 | %n\cppfile{geometria/rect.cpp} 91 | \subsection{Polygon Area} 92 | \cppfile{geometria/area.cpp} 93 | \subsection{Circle} 94 | \cppfile{geometria/circle.cpp} 95 | \subsection{Point in Poly} 96 | \cppfile{geometria/point.in.poly.cpp} 97 | \subsection{Point in Convex Poly log(n)} 98 | \cppfile{geometria/point.in.convex.poly.cpp} 99 | %\subsection{Convex Check CHECK} 100 | %\cppfile{geometria/convex.check.cpp} 101 | \subsection{Convex Hull} 102 | \cppfile{geometria/convex.hull.cpp} 103 | \subsection{Cut Polygon} 104 | \cppfile{geometria/cut.polygon.cpp} 105 | \subsection{Bresenham} 106 | \cppfile{geometria/bresenham.cpp} 107 | %\subsection{Rotate Matrix} 108 | %\cppfile{geometria/rotate.cpp} 109 | \subsection{Interseccion de Circulos en n3log(n)} 110 | \cppfile{geometria/int.circs.cpp} 111 | 112 | 113 | \section{Math}%%%%%%%%%%%%%%%%%%MATH%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 114 | \subsection{Identidades} 115 | { 116 | $\sum_{i=0}^n\binom{n}{i}=2^n$ 117 | 118 | $\sum_{i=0}^n i\binom{n}{i}=n*2^{n-1}$ 119 | 120 | $\sum_{i=m}^n i = \frac{n(n+1)}{2} - \frac{m(m-1)}{2} = \frac{(n+1-m)(n+m)}{2}$ 121 | 122 | $\sum_{i=0}^n i = \sum_{i=1}^n i = \frac{n(n+1)}{2}$ 123 | 124 | $\sum_{i=0}^n i^2 = \frac{n(n+1)(2n+1)}{6} = \frac{n^3}{3} + \frac{n^2}{2} + \frac{n}{6}$ 125 | 126 | $\sum_{i=0}^n i(i-1) = \frac{8}{6}(\frac{n}{2})(\frac{n}{2}+1)(n+1)$ (doubles) $\rightarrow$ Sino ver caso impar y par 127 | 128 | $\sum_{i=0}^n i^3 = \left(\frac{n(n+1)}{2}\right)^2 = \frac{n^4}{4} + \frac{n^3}{2} + \frac{n^2}{4} = \left[\sum_{i=1}^n i\right]^2$ 129 | 130 | $\sum_{i=0}^n i^4 = \frac{n(n+1)(2n+1)(3n^2+3n-1)}{30} = \frac{n^5}{5} + \frac{n^4}{2} + \frac{n^3}{3} - \frac{n}{30}$ 131 | 132 | $\sum_{i=0}^n i^p = \frac{(n+1)^{p+1}}{p+1} + \sum_{k=1}^p\frac{B_k}{p-k+1}{p\choose k}(n+1)^{p-k+1}$ 133 | 134 | $r=e-v+k+1$ 135 | 136 | Teorema de Pick: (Area, puntos interiores y puntos en el borde) 137 | 138 | $A=I+\frac{B}{2}-1$ 139 | 140 | 141 | }% 142 | \subsection{Ec. Caracteristica} 143 | $a_0T(n)+a_1T(n-1)+...+a_kT(n-k)=0$ 144 | 145 | $p(x)=a_0 x^k + a_1 x^{k-1} + ... + a_k$ 146 | 147 | Sean $r_1,r_2,...,r_q$ las raíces distintas, de mult. $m_1, m_2, ..., m_q$ 148 | 149 | $T(n)=\sum_{i=1}^q{\sum_{j=0}^{m_i - 1}c_{ij} n^j r_i^n}$ 150 | 151 | Las constantes $c_{ij}$ se determinan por los casos base. 152 | \subsection{Combinatorio} 153 | \cppfile{math/combinatorio.cpp} 154 | \subsection{Exp. de Numeros Mod.} 155 | \cppfile[2]{math/exp.mod.cpp} 156 | \subsection{Exp. de Matrices} 157 | \cppfile{math/exp.mat.cpp} 158 | \subsection{Matrices y determinante $O(n^3)$} 159 | \cppfile[17-52]{math/determinante.cpp} 160 | \subsection{Teorema Chino del Resto} 161 | $$y=\sum_{j=1}^n (x_j*(\prod_{i=1, i\neq j}^n m_i)_{m_j}^{-1}*\prod_{i=1, i\neq j}^n m_i)$$ 162 | \subsection{Criba} 163 | \cppfile[19-34 164 | ]{math/criba.cpp} 165 | \subsection{Funciones de primos} 166 | Sea $n=\prod{p_i^{k_i}}$, fact(n) genera un map donde a cada $p_i$ le asocia su $k_i$ 167 | \cppfile[33-88]{math/func.primos.cpp} 168 | \subsection{Phollard's Rho (rolando)} 169 | \cppfile{math/phollards.rho.villa.cpp} 170 | \subsection{GCD} 171 | \begin{code} 172 | tipo gcd(tipo a, tipo b){return a?gcd(b %a, a):b;} 173 | \end{code} 174 | \subsection{Extended Euclid} 175 | \cppfile{math/extended.euclid.cpp} 176 | \subsection{LCM} 177 | \begin{code} 178 | tipo lcm(tipo a, tipo b){return a / gcd(a,b) * b;} 179 | \end{code} 180 | \subsection{Inversos} 181 | \cppfile[7-16]{math/inversos.cpp} 182 | \subsection{Simpson} 183 | \cppfile{math/simpson.cpp} 184 | \subsection{Fraction} 185 | \cppfile{math/frac.cpp} 186 | \subsection{Polinomio} 187 | \cppfile[16-74]{math/polinomio.cpp} 188 | \subsection{Ec. Lineales} 189 | \cppfile[29-62]{math/eclineales.cpp} 190 | \subsection{FFT} 191 | \cppfile[16-65]{math/fft.cpp} 192 | \subsection{Tablas y cotas (Primos, Divisores, Factoriales, etc)} 193 | %\subsubsection{ 194 | 195 | \paragraph{Cantidad de primos menores que $10^n$}\ \\ 196 | $\pi(10^1)$ = 4 ; 197 | $\pi(10^2)$ = 25 ; 198 | $\pi(10^3)$ = 168 ; 199 | $\pi(10^4)$ = 1229 ; 200 | $\pi(10^5)$ = 9592 \\ 201 | $\pi(10^6)$ = 78.498 ; 202 | $\pi(10^7)$ = 664.579 ; 203 | $\pi(10^8)$ = 5.761.455 ; 204 | $\pi(10^9)$ = 50.847.534 \\ 205 | $\pi(10^{10})$ = 455.052,511 ; 206 | $\pi(10^{11})$ = 4.118.054.813 ; 207 | $\pi(10^{12})$ = 37.607.912.018% ; 208 | % 209 | % Fuente: http://primes.utm.edu/howmany.shtml#table 210 | % 211 | % 212 | 213 | %\subsubsection{Divisores} 214 | \paragraph{Divisores} \ \\ 215 | Cantidad de divisores ($\sigma_0$) para \emph{algunos} $n / \neg\exists n' 276 | //hacer cin.ignore() antes de getline() 277 | while(getline(cin, line)){ 278 | istringstream is(line); 279 | while(is >> X) 280 | cout << X << " "; 281 | cout << endl; 282 | } 283 | \end{code} 284 | \subsection*{Expandir pila} 285 | \begin{code} 286 | #include 287 | rlimit rl; 288 | getrlimit(RLIMIT_STACK, &rl); 289 | rl.rlim_cur=1024L*1024L*256L;//256mb 290 | setrlimit(RLIMIT_STACK, &rl); 291 | \end{code} 292 | \subsection*{Iterar subconjunto} 293 | \begin{code} 294 | for(int sbm=bm; sbm; sbm=(sbm-1)&bm) 295 | \end{code} 296 | \end{document} 297 | -------------------------------------------------------------------------------- /eldiego.tex: -------------------------------------------------------------------------------- 1 | % LaTeXar con : 2 | % pdflatex eldiego.tex 3 | %"The PDF file may contain up to 25 pages of reference material, single-sided, letter or A4 size, with text and illustrations readable by a person with correctable eyesight without magnification from a distance of 1/2 meter." 4 | \input{preamble.tex} 5 | \begin{document} 6 | \def\title{Caloventor en Dos - Universidad Nacional de Rosario} 7 | \centering{\includegraphics[width=3.5cm]{fotodiego}} 8 | \tableofcontents\newpage 9 | 10 | \section{algorithm}%%%%%%%%%%%%%%%%%%ALGORITHM%%%%%%%%%%%%%%%%%% 11 | \input{algorithm.tex} 12 | 13 | 14 | \section{Estructuras}%%%%%%%%%%%%%%%%%%ESTRUCTURAS%%%%%%%%%%%%%%%%%% 15 | \subsection{RMQ (static)} 16 | Dado un arreglo y una operacion asociativa \emph{idempotente}, get(i, j) opera sobre el rango [i, j). Restriccion: LVL $\ge$ ceil(logn); Usar [ ] para llenar arreglo y luego build(). 17 | \cppfile{estructuras/rmq.static.cpp} 18 | \subsection{RMQ (dynamic)} 19 | \cppfile{estructuras/rmq.dynamic.cpp} 20 | \subsection{RMQ (lazy)} 21 | \cppfile{estructuras/rmq.lazy.cpp} 22 | \subsection{RMQ (persistente)} 23 | \cppfile[23-53]{estructuras/rmq.persistent.cpp} 24 | \subsection{Fenwick Tree} 25 | \cppfile{estructuras/fenwick.cpp} 26 | \subsection{Union Find} 27 | \cppfile{grafos/union.find.cpp} 28 | \subsection{Disjoint Intervals} 29 | \cppfile{estructuras/disjoint.intervals.cpp} 30 | \subsection{RMQ (2D)} 31 | \cppfile{estructuras/rmq.2d.cpp} 32 | \subsection{Big Int} 33 | \cppfile{estructuras/bigint.cpp} 34 | \subsection{HashTables} 35 | \cppfile[16-30]{hash.cpp} 36 | \subsection{Modnum} 37 | \cppfile{estructuras/mnum.cpp} 38 | \subsection{Treap para set} 39 | \cppfile[16-89]{estructuras/treap.cpp} 40 | \subsection{Treap para arreglo} 41 | \cppfile[17-87]{estructuras/treaparr.cpp} 42 | \subsection{Convex Hull Trick} 43 | \cppfile[18-55]{estructuras/convexhull.trick.cpp} 44 | \subsection{Convex Hull Trick (Dynamic)} 45 | \cppfile[17-56]{estructuras/convexhull.trick.dyn.cpp} 46 | \subsection{Gain-Cost Set} 47 | \cppfile[20-43]{estructuras/gain-cost.set.cpp} 48 | \subsection{Set con busq binaria} 49 | \cppfile[17-26]{estructuras/order.tree.cpp} 50 | 51 | 52 | \section{Algos}%%%%%%%%%%%%%%%%%%ALGORITMOS%%%%%%%%%%%%%%%%%%%%%%%%%% 53 | \subsection{Longest Increasing Subsecuence} 54 | \cppfile[14-42]{algos/lis.cpp} 55 | \subsection{Alpha-Beta prunning} 56 | \cppfile{algos/alphabeta.cpp} 57 | \subsection{Mo's algorithm} 58 | \cppfile{algos/mosalgorithm.cpp} 59 | 60 | 61 | \section{Strings}%%%%%%%%%%%%%%%%%%STRINGS%%%%%%%%%%%%%%%%%%%%%%%%%% 62 | \subsection{Manacher} 63 | \cppfile[18-37]{string/manacher.cpp} 64 | \subsection{KMP} 65 | \cppfile[21-43]{string/kmp.cpp} 66 | \subsection{Trie} 67 | \cppfile{string/trie.cpp} 68 | %\subsection{Suffix Array (corto, nlog2n)} 69 | %\cppfile[12-26]{string/suffix.array.short.cpp} 70 | \subsection{Suffix Array (largo, nlogn)} 71 | \cppfile[-34]{string/suffix.array.cpp} 72 | \subsection{String Matching With Suffix Array} 73 | \cppfile[37-58]{string/suffix.array.cpp} 74 | \subsection{LCP (Longest Common Prefix)} 75 | \cppfile[60-75]{string/suffix.array.cpp} 76 | \subsection{Corasick} 77 | \cppfile[16-55]{string/corasick.cpp} 78 | \subsection{Suffix Automaton} 79 | \cppfile[16-61]{string/suffix.automaton.cpp} 80 | \subsection{Z Function} 81 | \cppfile[17-30]{string/zfunction.cpp} 82 | 83 | 84 | \section{Geometria}%%%%%%%%%%%%%%%%%%GEOMETRIA%%%%%%%%%%%%%%%%%%%%%% 85 | \subsection{Punto} 86 | \cppfile[2-33]{geometria/pto.cpp} 87 | \subsection{Orden radial de puntos} 88 | \cppfile{geometria/orden.radial.cpp} 89 | \subsection{Line} 90 | \cppfile{geometria/line.cpp} 91 | \subsection{Segment} 92 | \cppfile{geometria/segm.cpp} 93 | \subsection{Rectangle} 94 | \cppfile{geometria/rect.cpp} 95 | \subsection{Polygon Area} 96 | \cppfile{geometria/area.cpp} 97 | \subsection{Circle} 98 | \cppfile{geometria/circle.cpp} 99 | \subsection{Point in Poly} 100 | \cppfile{geometria/point.in.poly.cpp} 101 | \subsection{Point in Convex Poly log(n)} 102 | \cppfile{geometria/point.in.convex.poly.cpp} 103 | \subsection{Convex Check CHECK} 104 | \cppfile{geometria/convex.check.cpp} 105 | \subsection{Convex Hull} 106 | \cppfile{geometria/convex.hull.cpp} 107 | \subsection{Cut Polygon} 108 | \cppfile{geometria/cut.polygon.cpp} 109 | \subsection{Bresenham} 110 | \cppfile{geometria/bresenham.cpp} 111 | \subsection{Rotate Matrix} 112 | \cppfile{geometria/rotate.cpp} 113 | \subsection{Interseccion de Circulos en n3log(n)} 114 | \cppfile{geometria/int.circs.cpp} 115 | 116 | 117 | \section{Math}%%%%%%%%%%%%%%%%%%MATH%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 118 | \subsection{Identidades} 119 | { 120 | $\sum_{i=0}^n\binom{n}{i}=2^n$ 121 | 122 | $\sum_{i=0}^n i\binom{n}{i}=n*2^{n-1}$ 123 | 124 | $\sum_{i=m}^n i = \frac{n(n+1)}{2} - \frac{m(m-1)}{2} = \frac{(n+1-m)(n+m)}{2}$ 125 | 126 | $\sum_{i=0}^n i = \sum_{i=1}^n i = \frac{n(n+1)}{2}$ 127 | 128 | $\sum_{i=0}^n i^2 = \frac{n(n+1)(2n+1)}{6} = \frac{n^3}{3} + \frac{n^2}{2} + \frac{n}{6}$ 129 | 130 | $\sum_{i=0}^n i(i-1) = \frac{8}{6}(\frac{n}{2})(\frac{n}{2}+1)(n+1)$ (doubles) $\rightarrow$ Sino ver caso impar y par 131 | 132 | $\sum_{i=0}^n i^3 = \left(\frac{n(n+1)}{2}\right)^2 = \frac{n^4}{4} + \frac{n^3}{2} + \frac{n^2}{4} = \left[\sum_{i=1}^n i\right]^2$ 133 | 134 | $\sum_{i=0}^n i^4 = \frac{n(n+1)(2n+1)(3n^2+3n-1)}{30} = \frac{n^5}{5} + \frac{n^4}{2} + \frac{n^3}{3} - \frac{n}{30}$ 135 | 136 | $\sum_{i=0}^n i^p = \frac{(n+1)^{p+1}}{p+1} + \sum_{k=1}^p\frac{B_k}{p-k+1}{p\choose k}(n+1)^{p-k+1}$ 137 | 138 | $r=e-v+k+1$ 139 | 140 | Teorema de Pick: (Area, puntos interiores y puntos en el borde) 141 | 142 | $A=I+\frac{B}{2}-1$ 143 | 144 | 145 | }% 146 | \subsection{Ec. Caracteristica} 147 | $a_0T(n)+a_1T(n-1)+...+a_kT(n-k)=0$ 148 | 149 | $p(x)=a_0 x^k + a_1 x^{k-1} + ... + a_k$ 150 | 151 | Sean $r_1,r_2,...,r_q$ las raíces distintas, de mult. $m_1, m_2, ..., m_q$ 152 | 153 | $T(n)=\sum_{i=1}^q{\sum_{j=0}^{m_i - 1}c_{ij} n^j r_i^n}$ 154 | 155 | Las constantes $c_{ij}$ se determinan por los casos base. 156 | \subsection{Combinatorio} 157 | \cppfile{math/combinatorio.cpp} 158 | \subsection{Exp. de Numeros Mod.} 159 | \cppfile[2]{math/exp.mod.cpp} 160 | \subsection{Exp. de Matrices y Fibonacci en log(n)} 161 | \cppfile{math/exp.mat.cpp} 162 | \subsection{Matrices y determinante $O(n^3)$} 163 | \cppfile[17-77]{math/determinante.cpp} 164 | \subsection{Teorema Chino del Resto} 165 | $$y=\sum_{j=1}^n (x_j*(\prod_{i=1, i\neq j}^n m_i)_{m_j}^{-1}*\prod_{i=1, i\neq j}^n m_i)$$ 166 | \subsection{Criba} 167 | \cppfile[19-39]{math/criba.cpp} 168 | \subsection{Funciones de primos} 169 | Sea $n=\prod{p_i^{k_i}}$, fact(n) genera un map donde a cada $p_i$ le asocia su $k_i$ 170 | \cppfile[33-125]{math/func.primos.cpp} 171 | \subsection{Phollard's Rho (rolando)} 172 | \cppfile[16-84]{math/phollards.rho.cpp} 173 | \subsection{GCD} 174 | \begin{code} 175 | tipo gcd(tipo a, tipo b){return a?gcd(b %a, a):b;} 176 | \end{code} 177 | \subsection{Extended Euclid} 178 | \cppfile{math/extended.euclid.cpp} 179 | \subsection{LCM} 180 | \begin{code} 181 | tipo lcm(tipo a, tipo b){return a / gcd(a,b) * b;} 182 | \end{code} 183 | \subsection{Inversos} 184 | \cppfile[7-16]{math/inversos.cpp} 185 | \subsection{Simpson} 186 | \cppfile{math/simpson.cpp} 187 | \subsection{Fraction} 188 | \cppfile{math/frac.cpp} 189 | \subsection{Polinomio} 190 | \cppfile[22-91]{math/polinomio.cpp} 191 | \subsection{Ec. Lineales} 192 | \cppfile[29-62]{math/eclineales.cpp} 193 | \subsection{FFT} 194 | \cppfile[16-81]{math/fft.cpp} 195 | \subsection{Tablas y cotas (Primos, Divisores, Factoriales, etc)} 196 | %\subsubsection{ 197 | \paragraph{Factoriales} \ \\ 198 | \begin{tabular}{l|l} 199 | 0! = 1 & 11! = 39.916.800 \\ 200 | 1! = 1 & 12! = 479.001.600 ($\in \mathtt{int}$)\\ 201 | 2! = 2 & 13! = 6.227.020.800 \\ 202 | 3! = 6 & 14! = 87.178.291.200 \\ 203 | 4! = 24 & 15! = 1.307.674.368.000 \\ 204 | 5! = 120 & 16! = 20.922.789.888.000 \\ 205 | 6! = 720 & 17! = 355.687.428.096.000 \\ 206 | 7! = 5.040 & 18! = 6.402.373.705.728.000 \\ 207 | 8! = 40.320 & 19! = 121.645.100.408.832.000 \\ 208 | 9! = 362.880 & 20! = 2.432.902.008.176.640.000 ($\in \mathtt{tint}$) \\ 209 | 10! = 3.628.800 & 21! = 51.090.942.171.709.400.000 210 | \end{tabular} 211 | 212 | max signed tint = 9.223.372.036.854.775.807 \\ 213 | max unsigned tint = 18.446.744.073.709.551.615 214 | %\subsubsection{ 215 | \paragraph{Primos} \ \\ 216 | 2 3 5 7 11 13 17 19 23 29 217 | 31 37 41 43 47 53 59 61 67 71 218 | 73 79 83 89 97 101 103 107 109 113 219 | 127 131 137 139 149 151 157 163 167 173 220 | 179 181 191 193 197 199 211 223 227 229 221 | 233 239 241 251 257 263 269 271 277 281 222 | 283 293 307 311 313 317 331 337 347 349 223 | 353 359 367 373 379 383 389 397 401 409 224 | 419 421 431 433 439 443 449 457 461 463 225 | 467 479 487 491 499 503 509 521 523 541 226 | 547 557 563 569 571 577 587 593 599 601 227 | 607 613 617 619 631 641 643 647 653 659 228 | 661 673 677 683 691 701 709 719 727 733 229 | 739 743 751 757 761 769 773 787 797 809 230 | 811 821 823 827 829 839 853 857 859 863 231 | 877 881 883 887 907 911 919 929 937 941 232 | 947 953 967 971 977 983 991 997 1009 1013 233 | 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069 234 | 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151 235 | 1153 1163 1171 1181 1187 1193 1201 1213 1217 1223 236 | 1229 1231 1237 1249 1259 1277 1279 1283 1289 1291 237 | 1297 1301 1303 1307 1319 1321 1327 1361 1367 1373 238 | 1381 1399 1409 1423 1427 1429 1433 1439 1447 1451 239 | 1453 1459 1471 1481 1483 1487 1489 1493 1499 1511 240 | 1523 1531 1543 1549 1553 1559 1567 1571 1579 1583 241 | 1597 1601 1607 1609 1613 1619 1621 1627 1637 1657 242 | 1663 1667 1669 1693 1697 1699 1709 1721 1723 1733 243 | 1741 1747 1753 1759 1777 1783 1787 1789 1801 1811 244 | 1823 1831 1847 1861 1867 1871 1873 1877 1879 1889 245 | 1901 1907 1913 1931 1933 1949 1951 1973 1979 1987 246 | 1993 1997 1999 2003 2011 2017 2027 2029 2039 2053 247 | 2063 2069 2081 248 | 249 | %2083 2087 2089 2099 2111 2113 2129 250 | %2131 2137 2141 2143 2153 2161 2179 2203 2207 2213 251 | %2221 2237 2239 2243 2251 2267 2269 2273 2281 2287 252 | %2293 2297 2309 2311 2333 2339 2341 2347 2351 2357 253 | %2371 2377 2381 2383 2389 2393 2399 2411 2417 2423 254 | %2437 2441 2447 2459 2467 2473 2477 2503 2521 2531 255 | %2539 2543 2549 2551 2557 2579 2591 2593 2609 2617 256 | %2621 2633 2647 2657 2659 2663 2671 2677 2683 2687 257 | %2689 2693 2699 2707 2711 2713 2719 2729 2731 2741 258 | %2749 2753 2767 2777 2789 2791 2797 2801 2803 2819 259 | %2833 2837 2843 2851 2857 2861 2879 2887 2897 2903 260 | %2909 2917 2927 2939 2953 2957 2963 2969 2971 2999 261 | %3001 3011 3019 3023 3037 3041 3049 3061 3067 3079 262 | %3083 3089 3109 3119 3121 3137 3163 3167 3169 3181 263 | %3187 3191 3203 3209 3217 3221 3229 3251 3253 3257 264 | %3259 3271 3299 3301 3307 3313 3319 3323 3329 3331 265 | %3343 3347 3359 3361 3371 3373 3389 3391 3407 3413 266 | %3433 3449 3457 3461 3463 3467 3469 3491 3499 3511 267 | %3517 3527 3529 3533 3539 3541 3547 3557 3559 3571\\ 268 | \paragraph{Primos cercanos a $10^n$}\ \\ 269 | 9941 9949 9967 9973 10007 10009 10037 10039 10061 10067 10069 10079\\ 270 | 99961 99971 99989 99991 100003 100019 100043 100049 100057 100069\\ 271 | 999959 999961 999979 999983 1000003 1000033 1000037 1000039\\ 272 | 9999943 9999971 9999973 9999991 10000019 10000079 10000103 10000121\\ 273 | 99999941 99999959 99999971 99999989 100000007 100000037 100000039 100000049\\ 274 | 999999893 999999929 999999937 1000000007 1000000009 1000000021 1000000033 275 | 276 | \paragraph{Cantidad de primos menores que $10^n$}\ \\ 277 | $\pi(10^1)$ = 4 ; 278 | $\pi(10^2)$ = 25 ; 279 | $\pi(10^3)$ = 168 ; 280 | $\pi(10^4)$ = 1229 ; 281 | $\pi(10^5)$ = 9592 \\ 282 | $\pi(10^6)$ = 78.498 ; 283 | $\pi(10^7)$ = 664.579 ; 284 | $\pi(10^8)$ = 5.761.455 ; 285 | $\pi(10^9)$ = 50.847.534 \\ 286 | $\pi(10^{10})$ = 455.052,511 ; 287 | $\pi(10^{11})$ = 4.118.054.813 ; 288 | $\pi(10^{12})$ = 37.607.912.018% ; 289 | % 290 | % Fuente: http://primes.utm.edu/howmany.shtml#table 291 | % 292 | % 293 | 294 | %\subsubsection{Divisores} 295 | \paragraph{Divisores} \ \\ 296 | Cantidad de divisores ($\sigma_0$) para \emph{algunos} $n / \neg\exists n' 374 | cout << setprecision(2) << fixed; 375 | \end{code} 376 | \subsection*{Rellenar con espacios(para justificar)} 377 | \begin{code} 378 | #include 379 | cout << setfill(' ') << setw(3) << 2 << endl; 380 | \end{code} 381 | \subsection*{Leer hasta fin de linea} 382 | \begin{code} 383 | #include 384 | //hacer cin.ignore() antes de getline() 385 | while(getline(cin, line)){ 386 | istringstream is(line); 387 | while(is >> X) 388 | cout << X << " "; 389 | cout << endl; 390 | } 391 | \end{code} 392 | \subsection*{Aleatorios} 393 | \begin{code} 394 | #define RAND(a, b) (rand()%(b-a+1)+a) 395 | srand(time(NULL)); 396 | \end{code} 397 | \subsection*{Doubles Comp.} 398 | \begin{code} 399 | const double EPS = 1e-9; 400 | x == y <=> fabs(x-y) < EPS 401 | x > y <=> x > y + EPS 402 | x >= y <=> x > y - EPS 403 | \end{code} 404 | \subsection*{Limites} 405 | \begin{code} 406 | #include 407 | numeric_limits 408 | ::max() 409 | ::min() 410 | ::epsilon() 411 | \end{code} 412 | \subsection*{Muahaha} 413 | \begin{code} 414 | #include 415 | void divzero(int p){ 416 | while(true);} 417 | void segm(int p){ 418 | exit(0);} 419 | //in main 420 | signal(SIGFPE, divzero); 421 | signal(SIGSEGV, segm); 422 | \end{code} 423 | \subsection*{Mejorar velocidad} 424 | \begin{code} 425 | ios::sync_with_stdio(false); 426 | \end{code} 427 | \subsection*{Mejorar velocidad 2} 428 | \begin{code} 429 | //Solo para enteros positivos 430 | inline void Scanf(int& a){ 431 | char c = 0; 432 | while(c<33) c = getc(stdin); 433 | a = 0; 434 | while(c>33) a = a*10 + c - '0', c = getc(stdin); 435 | } 436 | \end{code} 437 | \subsection*{Expandir pila} 438 | \begin{code} 439 | #include 440 | rlimit rl; 441 | getrlimit(RLIMIT_STACK, &rl); 442 | rl.rlim_cur=1024L*1024L*256L;//256mb 443 | setrlimit(RLIMIT_STACK, &rl); 444 | \end{code} 445 | \subsection*{C++11} 446 | \begin{code} 447 | g++ --std=c++1 448 | \end{code} 449 | \subsection*{Leer del teclado} 450 | \begin{code} 451 | freopen("/dev/tty", "a", stdin); 452 | \end{code} 453 | \subsection*{Iterar subconjunto} 454 | \begin{code} 455 | for(int sbm=bm; sbm; sbm=(sbm-1)&bm) 456 | \end{code} 457 | \subsection*{File setup} 458 | \begin{code} 459 | //tambien se pueden usar comas: {a, x, m, l} 460 | touch {a..l}.in; tee {a..l}.cpp < template.cpp 461 | \end{code} 462 | \end{document} 463 | --------------------------------------------------------------------------------