diff --git a/2D Segtree.cpp b/2D Segtree.cpp deleted file mode 100644 index fba17b5..0000000 --- a/2D Segtree.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include -using namespace std; -#define pb push_back -#define ll long long int - -typedef struct node { - int l,r,x,y; - ll val; - struct node *ul,*ur,*lll,*lr; -} node; - -int ar[1030][1030]; -ll kam,zyada; - -node* build(int l,int r,int x,int y) { - //cout<r || x>y) return NULL; - node* ne = (node*)malloc(sizeof(node)); - ne->l = l; - ne->r = r; - ne->y = y; - ne->x = x; - if(l==r&&x==y) { - ne->val = ar[l][x]; - return ne; - } - ne->ul = build(l,(l+r)/2,x,(x+y)/2); - if(ne->ul) - ne->val += ne->ul->val;//.pb(ne->ul->ve[i]); - ne->ur = build(l,(l+r)/2,(x+y)/2+1,y); - if(ne->ur) - ne->val += ne->ur->val;//.pb(ne->ur->ve[i]); - ne->lll = build((l+r)/2+1,r,x,(x+y)/2); - if(ne->lll) - ne->val += ne->lll->val;//.pb(ne->ur->ve[i]); - ne->lr = build((l+r)/2+1,r,(x+y)/2+1,y); - if(ne->lr) - ne->val += ne->lr->val;//.pb(ne->ur->ve[i]); - return ne; -} - -void query(node *t,int l1,int r1,int x1,int y1,int l2,int r2,int x2,int y2) { -// cout<r1||x1>y1) return; - if(l1>=l2 && r1<=r2 && x1>=x2 && y1<=y2) { - kam += t->val; - return; - } - if(l2<=(l1+r1)/2 && x2<=(x1+y1)/2) - query(t->ul,l1,(l1+r1)/2,x1,(x1+y1)/2,l2,r2,x2,y2); - if(l2<=(l1+r1)/2 && y2>(x1+y1)/2) - query(t->ur,l1,(l1+r1)/2,(x1+y1)/2+1,y1,l2,r2,x2,y2); - if(r2>(l1+r1)/2 && x2<=(x1+y1)/2) - query(t->lll,(l1+r1)/2+1,r1,x1,(x1+y1)/2,l2,r2,x2,y2); - if(r2>(l1+r1)/2 && y2>(x1+y1)/2) - query(t->lr,(l1+r1)/2+1,r1,(x1+y1)/2+1,y1,l2,r2,x2,y2); -} - -void update(node *t,int l1,int r1,int x1,int y1,int l2,int x2,int val1,int val2) { - //cout<r1||x1>y1) return; - t->val += val2; - t->val -= val1; - if(l1==r1&&x1==y1) return; - if(l2<=(l1+r1)/2 && x2<=(x1+y1)/2) - update(t->ul,l1,(l1+r1)/2,x1,(x1+y1)/2,l2,x2,val1,val2); - if(l2<=(l1+r1)/2 && x2>(x1+y1)/2) - update(t->ur,l1,(l1+r1)/2,(x1+y1)/2+1,y1,l2,x2,val1,val2); - if(l2>(l1+r1)/2 && x2<=(x1+y1)/2) - update(t->lll,(l1+r1)/2+1,r1,x1,(x1+y1)/2,l2,x2,val1,val2); - if(l2>(l1+r1)/2 && x2>(x1+y1)/2) - update(t->lr,(l1+r1)/2+1,r1,(x1+y1)/2+1,y1,l2,x2,val1,val2); -} - -int main() { - ios::sync_with_stdio(false);cin.tie(0); - int t; - cin>>t; - while(t--) { - node* head = (node*)malloc(sizeof(node)); - int i,j,k,l,n,x,q,y,r; - string s; - cin>>n; - for(i=0;i>s; - while(s[0]=='S') { - cin>>l>>r>>x; - kam=0; - if(s[1]=='U') { - cin>>y; - query(head,0,n-1,0,n-1,l,x,r,y); - cout<>s; - } - } - return 0; -} diff --git a/3D hull.cpp b/3D hull.cpp deleted file mode 100644 index aa07344..0000000 --- a/3D hull.cpp +++ /dev/null @@ -1,82 +0,0 @@ -template struct Point3D { - typedef Point3D P; - typedef const P& R; - T x, y, z; - explicit Point3D(T x=0, T y=0, T z=0) : x(x), y(y), z(z) {} - bool operator<(R p) const { - return tie(x, y, z) < tie(p.x, p.y, p.z); } - bool operator==(R p) const { - return tie(x, y, z) == tie(p.x, p.y, p.z); } - P operator+(R p) const { return P(x+p.x, y+p.y, z+p.z); } - P operator-(R p) const { return P(x-p.x, y-p.y, z-p.z); } - P operator*(T d) const { return P(x*d, y*d, z*d); } - P operator/(T d) const { return P(x/d, y/d, z/d); } - T dot(R p) const { return x*p.x + y*p.y + z*p.z; } - P cross(R p) const { - return P(y*p.z - z*p.y, z*p.x - x*p.z, x*p.y - y*p.x); - } - T dist2() const { return x*x + y*y + z*z; } - double dist() const { return sqrt((double)dist2()); } - //Azimuthal angle (longitude) to x-axis in interval [-pi, pi] - double phi() const { return atan2(y, x); } - //Zenith angle (latitude) to the z-axis in interval [0, pi] - double theta() const { return atan2(sqrt(x*x+y*y),z); } - P unit() const { return *this/(T)dist(); } //makes dist()=1 - //returns unit vector normal to *this and p - P normal(P p) const { return cross(p).unit(); } - //returns point rotated 'angle' radians ccw around axis - P rotate(double angle, P axis) const { - double s = sin(angle), c = cos(angle); P u = axis.unit(); - return u*dot(u)*(1-c) + (*this)*c - cross(u)*s; - } -}; - -typedef Point3D P3; - -struct PR { - void ins(int x) { (a == -1 ? a : b) = x; } - void rem(int x) { (a == x ? a : b) = -1; } - int cnt() { return (a != -1) + (b != -1); } - int a, b; -}; - -struct F { P3 q; int a, b, c; }; - -vector hull3d(const vector& A) { - assert(sz(A) >= 4); - vector> E(sz(A), vector(sz(A), {-1, -1})); -#define E(x,y) E[f.x][f.y] - vector FS; - auto mf = [&](int i, int j, int k, int l) { - P3 q = (A[j] - A[i]).cross((A[k] - A[i])); - if (q.dot(A[l]) > q.dot(A[i])) - q = q * -1; - F f{q, i, j, k}; - E(a,b).ins(k); E(a,c).ins(j); E(b,c).ins(i); - FS.push_back(f); - }; - rep(i,0,4) rep(j,i+1,4) rep(k,j+1,4) - mf(i, j, k, 6 - i - j - k); - - rep(i,4,sz(A)) { - rep(j,0,sz(FS)) { - F f = FS[j]; - if(f.q.dot(A[i]) > f.q.dot(A[f.a])) { - E(a,b).rem(f.c); - E(a,c).rem(f.b); - E(b,c).rem(f.a); - swap(FS[j--], FS.back()); - FS.pop_back(); - } - } - int nw = sz(FS); - rep(j,0,nw) { - F f = FS[j]; -#define C(a, b, c) if (E(a,b).cnt() != 2) mf(f.a, f.b, i, f.c); - C(a, b, c); C(a, c, b); C(b, c, a); - } - } - trav(it, FS) if ((A[it.b] - A[it.a]).cross( - A[it.c] - A[it.a]).dot(it.q) <= 0) swap(it.c, it.b); - return FS; -}; diff --git a/Aho Corsik.cpp b/Aho Corsik.cpp deleted file mode 100644 index ccbba24..0000000 --- a/Aho Corsik.cpp +++ /dev/null @@ -1,152 +0,0 @@ -#define inc(i,a,b) for(int i=a;i<=b;++i) -#define pb push_back - -const int maxWords = 506, maxLyrics = 106, maxWordLength = 5006, maxLyricLength = 50006; - -struct node { - int occ, failIndegree; - map edge; - node* fail; - - node():occ(0),failIndegree(0),fail(NULL) {} -}root; - -int numWords, numLyrics; -node* id[maxWords]; - -void preComputation(); -void searchTarget(); -void getOccurances(); -void buildTrie(); -void buildAutomaton(); - -int main() { - scanf("%d",&numWords); - preComputation(); - - scanf("%d",&numLyrics); - inc(i,1,numLyrics) { - searchTarget(); - } - getOccurances(); - - inc(i,0,numWords-1) { - printf("%d\n",id[i]->occ); - } -} - -void buildTrie() { - char word[maxWordLength], c; - - inc(i,0,numWords-1) { - cin >> word; - id[i] = &root; - - for(int j=0;word[j];++j) { - c = word[j]; - assert(isalnum(c) || c=='-'); - if(!id[i]->edge.count(c)) { - id[i]->edge[c] = new node; - } - id[i] = id[i]->edge[c]; - } - } -} -void buildAutomaton() { - queue q; - - vector alpha; - inc(i,'a','z') alpha.pb(i); - inc(i,'A','Z') alpha.pb(i); - inc(i,'0','9') alpha.pb(i); - alpha.pb('-'); - - // Gives root more failIndegree so that it isn't added to queue in getOccurances() - root.failIndegree = 1; - - inc(i,0,alpha.size()-1) { - if(!root.edge.count(alpha[i])) { - root.edge[alpha[i]] = &root; - } - else { - root.edge[alpha[i]]->fail = &root; - (root.failIndegree)++; - q.push(root.edge[alpha[i]]); - } - } - - while(!q.empty()) { - node* p = q.front(); - q.pop(); - - map::iterator it = p->edge.begin(); - for(;it!=p->edge.end();++it) { - node *u = it->second; - char c = it->first; - - node *v = p->fail; - while(!v->edge.count(c)) { - - v = v->fail; - } - u->fail = v->edge[c]; - (v->edge[c]->failIndegree)++; - - q.push(u); - } - } -} -void preComputation() { - buildTrie(); - buildAutomaton(); -} -void searchTarget() { - char lyric[maxLyricLength]; - scanf(" %s",lyric); - - node* curr = &root; - char c; - for(int i=0;lyric[i];++i) { - c = lyric[i]; - while(!curr->edge.count(c)) { - assert(curr->fail != NULL); - curr = curr->fail; - } - curr = curr->edge[c]; - (curr->occ)++; - } -} -void getOccurances() { - queue q; - - queue bfs; - bfs.push(&root); - while(!bfs.empty()) { - node* u = bfs.front(); - bfs.pop(); - - if(!u->failIndegree) q.push(u); - - map::iterator it = u->edge.begin(); - for(;it!=u->edge.end();++it) { - node* v = it->second; - if(v!=(&root)) bfs.push(v); - } - } - - while(!q.empty()) { - node* u = q.front(); - q.pop(); - - assert(u->fail != NULL); - node* v = u->fail; - - (v->failIndegree)--; - if(!v->failIndegree) { - assert(v!=(&root)); - q.push(v); - } - - v->occ += u->occ; - } -} diff --git a/BFS.cpp b/BFS.cpp deleted file mode 100644 index da0db4c..0000000 --- a/BFS.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include -#include - -using namespace std; - -//COPY THE BLACKBOX, there is no need to change anything in it. -//Check the main function at bottom for USAGE - -//****************BLACKBOX START***************** -//START COPYING FROM HERE -class Graph { - public: - - Graph(int num_nodes) - : adj_list(num_nodes), dist(num_nodes, -1) {} - - void add_edge(int start, int end); - vector> adj_list; - vector dist; -}; - -void Graph::add_edge(int start, int end) { - adj_list[start].push_back(end); -} - -vector BFS(Graph& g, int source) { - vector visited(g.adj_list.size(), false); - queue q; - q.push(source); - - visited[source] = true; - g.dist[source] = 0; - - while(!q.empty()) { - int cur_node = q.front(); - vector cur_node_adj = g.adj_list[cur_node]; - - for (unsigned int i = 0; i < cur_node_adj.size(); ++i) { - int adj_node = cur_node_adj[i]; - if (visited[adj_node] == false) { - visited[adj_node] = true; - g.dist[adj_node] = g.dist[cur_node] + 1; - q.push(adj_node); - } - } - q.pop(); - } - - return g.dist; -} -//END COPYING HERE -//********************BLACKBOX END****************** - - -int main() { - // initaitise a graph with 4 nodes, nodes are 0-indexed - Graph g(4); - - //DIRECTED GRAPH : add edges `Node 0 -> Node 4` and `Node 1 -> Node 3` - g.add_edge(0,4); - g.add_edge(1,3); - - //UNDIRECT GRAPH : add edges between `Node 0 -- Node 4` and `Node 1 -- Node 3` - g.add_edge(0,4); - g.add_edge(4,0); - g.add_edge(1,3); - g.add_edge(3,1); - - //do BFS on the graph g start at `Node 2` - //An array of size "number of nodes" is returned with the minimum distance from `Node 2` to each node, i.e. `shortest path length from Node 2 -> Node 3 = min_dist[3] ` - //If a `Node i` is unreachable from `Node 2`, then `min_dist[i]=-1` - vectormin_dist = BFS(g, 2); - - - return 0; -} diff --git a/BFS_Graph_template.cpp b/BFS_Graph_template.cpp deleted file mode 100644 index a445aa4..0000000 --- a/BFS_Graph_template.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// BFS algorithm in C++ - -#include -#include - -using namespace std; - -//********************* BLACKBOX STARTS -// Copy this section as it is (Refer main function at bottom for usage, that is all that you need) -class Graph { - int numVertices; - list* adjLists; - bool* visited; - - public: - Graph(int vertices); - void addEdge(int src, int dest); - void BFS(int startVertex); -}; - -// Create a graph with given vertices, -// and maintain an adjacency list -Graph::Graph(int vertices) { - numVertices = vertices; - adjLists = new list[vertices]; -} - -// Add edges to the graph -void Graph::addEdge(int src, int dest) { - adjLists[src].push_back(dest); -} - -// BFS algorithm -void Graph::BFS(int startVertex) { - visited = new bool[numVertices]; - for (int i = 0; i < numVertices; i++) - visited[i] = false; - - list queue; - - visited[startVertex] = true; - queue.push_back(startVertex); - - list::iterator i; - - while (!queue.empty()) { - int currVertex = queue.front(); - cout << "Visited " << currVertex << " "; - queue.pop_front(); - - for (i = adjLists[currVertex].begin(); i != adjLists[currVertex].end(); ++i) { - int adjVertex = *i; - if (!visited[adjVertex]) { - visited[adjVertex] = true; - queue.push_back(adjVertex); - } - } - } -} -//BLACKBOX ENDS -//************************* - -int main() { - Graph g(4); //Create new Graph g with 4 nodes - g.addEdge(0, 1); //Add DIRECTED edges to graph g from 0 to 1. If you have UNDIRECTED graph, simply also add edge(1->0) - g.addEdge(0, 2); - g.addEdge(1, 2); - g.addEdge(2, 0); - g.addEdge(2, 3); - g.addEdge(3, 3); - - g.BFS(2); - - return 0; -} diff --git a/Chinese Remainder Theorem.cpp b/Chinese Remainder Theorem.cpp deleted file mode 100644 index baa0e79..0000000 --- a/Chinese Remainder Theorem.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* \texttt{chinese(a, m, b, n)} returns a number $x$, such that - * $x\equiv a \pmod m$ and $x\equiv b \pmod n$. For not - * coprime $n, m$, use \texttt{chinese\_common}. Note that all numbers must be less than - * $2^{31}$ if you have Z = unsigned long long. - * Status: Works - * Time: $\log(m + n)$ - */ -ll euclid(ll a, ll b, ll &x, ll &y) { - if (b) { ll d = euclid(b, a % b, y, x); - return y -= a/b * x, d; } - return x = 1, y = 0, a; -} -template Z chinese(Z a, Z m, Z b, Z n) { - Z x, y; euclid(m, n, x, y); - Z ret = a * (y + m) % m * n + b * (x + n) % n * m; - if (ret >= m * n) ret -= m * n; - return ret; -} - -template Z chinese_common(Z a, Z m, Z b, Z n) { - Z d = gcd(m, n); - if (((b -= a) %= n) < 0) b += n; - if (b % d) return -1; // No solution - return d * chinese(Z(0), m/d, b/d, n/d) + a; -} diff --git a/DP_Opti : Divide & Conquer.cpp b/DP_Opti : Divide & Conquer.cpp deleted file mode 100644 index ac7c47b..0000000 --- a/DP_Opti : Divide & Conquer.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/*Given $a[i] = \min_{lo(i) \le k < hi(i)}(f(i, k))$ where the (minimal) optimal $k$ increases with $i$, computes $a[i]$ for $i = L..R-1$. - * Status: tested on http://codeforces.com/contest/321/problem/E - * Time: O((N + (hi-lo)) \log N) */ -struct DP { // Modify at will: - int lo(int ind) { return 0; } - int hi(int ind) { return ind; } - ll f(int ind, int k) { return dp[ind][k]; } - void store(int ind, int k, ll v) { res[ind] = pii(k, v); } - - void rec(int L, int R, int LO, int HI) { - if (L >= R) return; - int mid = (L + R) >> 1; - pair best(LLONG_MAX, LO); - rep(k, max(LO,lo(mid)), min(HI,hi(mid))) - best = min(best, make_pair(f(mid, k), k)); - store(mid, best.second, best.first); - rec(L, mid, LO, best.second+1); - rec(mid+1, R, best.second, HI); - } - void solve(int L, int R) { rec(L, R, INT_MIN, INT_MAX); } -}; diff --git a/DSU.cpp b/DSU.cpp deleted file mode 100644 index a429683..0000000 --- a/DSU.cpp +++ /dev/null @@ -1,17 +0,0 @@ -struct DSU { - //int gans=0; - int root(int v){return par[v] < 0 ? v : (par[v] = root(par[v]));} - void merge(int x,int y){ - if((x = root(x)) == (y = root(y))) return ; - if(par[y] < par[x]) swap(x, y); - par[x] += par[y]; - par[y] = x; - //int tmp=val[x]+val[y]; - //val[x]=val[y]=tmp; - //gans=max(gans,tmp); - } -} dsu; - -//Initially par[i]=-1 for all. -//If each block has initial size (see TWOFL in cc) -// -par[v]=size of block representing v. diff --git a/Delauney.cpp b/Delauney.cpp deleted file mode 100644 index 5d822d2..0000000 --- a/Delauney.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Running time: O(n^4) -// -// INPUT: x[] = x-coordinates -// y[] = y-coordinates -// -// OUTPUT: triples = a vector containing m triples of indices -// corresponding to triangle vertices - -#include -using namespace std; - -typedef double T; - -struct triple { - int i, j, k; - triple() {} - triple(int i, int j, int k) : i(i), j(j), k(k) {} -}; - -vector delaunayTriangulation(vector& x, vector& y) { - int n = x.size(); - vector z(n); - vector ret; - - for (int i = 0; i < n; i++) - z[i] = x[i] * x[i] + y[i] * y[i]; - - for (int i = 0; i < n-2; i++) { - for (int j = i+1; j < n; j++) { - for (int k = i+1; k < n; k++) { - if (j == k) continue; - double xn = (y[j]-y[i])*(z[k]-z[i]) - (y[k]-y[i])*(z[j]-z[i]); - double yn = (x[k]-x[i])*(z[j]-z[i]) - (x[j]-x[i])*(z[k]-z[i]); - double zn = (x[j]-x[i])*(y[k]-y[i]) - (x[k]-x[i])*(y[j]-y[i]); - bool flag = zn < 0; - for (int m = 0; flag && m < n; m++) - flag = flag && ((x[m]-x[i])*xn + - (y[m]-y[i])*yn + - (z[m]-z[i])*zn <= 0); - if (flag) ret.push_back(triple(i, j, k)); - } - } - } - return ret; -} -int main() { - T xs[]={0, 0, 1, 0.9}; - T ys[]={0, 1, 0, 0.9}; - vector x(&xs[0], &xs[4]), y(&ys[0], &ys[4]); - vector tri = delaunayTriangulation(x, y); - - //expected: 0 1 3 - // 0 3 2 - - int i; - for(i = 0; i < tri.size(); i++) printf("%d %d %d\n", tri[i].i, tri[i].j, tri[i].k); -} diff --git a/Dynamic Convex Hull.cpp b/Dynamic Convex Hull.cpp deleted file mode 100644 index ff63bb8..0000000 --- a/Dynamic Convex Hull.cpp +++ /dev/null @@ -1,35 +0,0 @@ -const ll is_query = -(1LL<<62); -struct Line { - ll m, b; - mutable function succ; - bool operator<(const Line& rhs) const { - if (rhs.b != is_query) return m < rhs.m; - const Line* s = succ(); - if (!s) return 0; - ll x = rhs.m; - return b - s->b < (s->m - m) * x; - } -}; -struct HullDynamic : public multiset { // will maintain upper hull for maximum - bool bad(iterator y) { - auto z = next(y); - if (y == begin()) { - if (z == end()) return 0; - return y->m == z->m && y->b <= z->b; - } - auto x = prev(y); - if (z == end()) return y->m == x->m && y->b <= x->b; - return (x->b - y->b)*(z->m - y->m) >= (y->b - z->b)*(y->m - x->m); - } - void insert_line(ll m, ll b) { - auto y = insert({ m, b }); - y->succ = [=] { return next(y) == end() ? 0 : &*next(y); }; - if (bad(y)) { erase(y); return; } - while (next(y) != end() && bad(next(y))) erase(next(y)); - while (y != begin() && bad(prev(y))) erase(prev(y)); - } - ll eval(ll x) { - auto l = *lower_bound((Line) { x, is_query }); - return l.m * x + l.b; - } -}; diff --git a/FFT.cpp b/FFT.cpp deleted file mode 100644 index ab73d5a..0000000 --- a/FFT.cpp +++ /dev/null @@ -1,39 +0,0 @@ -using cd = complex; -const double PI = acos(-1); -int reverse(int num, int lg_n) { - int res = 0; - for (int i = 0; i < lg_n; i++) if (num & (1 << i)) res |= 1 << (lg_n - 1 - i); - return res; -} -void fft(vector & a, bool invert) { - int n = a.size(); - int lg_n = 0; - while ((1 << lg_n) < n) lg_n++; - for (int i = 0; i < n; i++) if (i < reverse(i, lg_n)) swap(a[i], a[reverse(i, lg_n)]); - for (int len = 2; len <= n; len <<= 1) { - double ang = 2 * PI / len * (invert ? -1 : 1); - cd wlen(cos(ang), sin(ang)); - for (int i = 0; i < n; i += len) { - cd w(1); - for (int j = 0; j < len / 2; j++) { - cd u = a[i+j], v = a[i+j+len/2] * w; - a[i+j] = u + v; - a[i+j+len/2] = u - v; - w *= wlen; - } - } - } - if (invert) { for (cd & x : a) x /= n;} -} -vector multiply(vector const& a, vector const& b) { - vector fa(a.begin(), a.end()), fb(b.begin(), b.end()); - int n = 1; - while (n < a.size() + b.size()) n <<= 1; - fa.resize(n);fb.resize(n); - fft(fa, false);fft(fb, false); - for (int i = 0; i < n; i++) fa[i] *= fb[i]; - fft(fa, true); - vector result(n); - for (int i = 0; i < n; i++) result[i] = round(fa[i].real()); - return result; -} diff --git a/Graph Power Library.cpp b/Graph Power Library.cpp deleted file mode 100644 index 001b723..0000000 --- a/Graph Power Library.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#include -using namespace std; - - -//COPY THE BLACKBOX, there is no need to change anything in it. -//Check the main function at bottom for USAGE - -//****************BLACKBOX START***************** -//START COPYING FROM HERE - -typedef int ll; - -class Graph { - - bool is_directed; - - public: - vector>>adj; - int n,N=2000000; - Graph(int n_, bool is_directed_){ - n=n_; is_directed = is_directed_; - adj.resize(N,vector>()); - } - - int hash(int u, int v){ - return u*1873+v; - } - int hash(int u, int v, int k){ - return k*1873*1873+u*1873+v; - } - bool node_has_edges(int u) { - return (adj[u].size()!=0); - } - bool node_has_edges(int u, int v) { - int x = hash(u,v); - return (adj[x].size()!=0); - } - bool node_has_edges(int u, int v, int k) { - int x = hash(u,v,k); - return (adj[x].size()!=0); - } - - void add_edge(int u, int v, ll c=0){ - add_edge_weighted_undirected(u,v,c); - if(!is_directed) - add_edge_weighted_undirected(v,u,c); - } - void add_edge(int ui, int uj, int vi, int vj, ll c=0){ - int u=hash(ui,uj), v=hash(vi,vj); - add_edge_weighted_undirected(u,v,c); - if(!is_directed) - add_edge_weighted_undirected(v,u,c); - } - void add_edge(int ui, int uj,int uk, int vi, int vj, int vk, ll c=0){ - int u=hash(ui,uj,uk), v=hash(vi,vj,vk); - add_edge_weighted_undirected(u,v,c); - if(!is_directed) - add_edge_weighted_undirected(v,u,c); - } - - private : - - void add_edge_weighted_undirected(int u, int v, ll c) { - pairp = make_pair(v,c); - adj[u].push_back(p); - } - -}; - -class BFS { - vectormin_dist_from_source; - vector visited; - - public: - BFS(Graph *g_) { - g = g_; - min_dist_from_source.resize(g->N,-1); - visited.resize(g->N, false); - } - Graph *g; - - - void run(int source) { - queue q; - q.push(source); - - visited[source] = true; - min_dist_from_source[source] = 0; - - while(!q.empty()) { - int cur_node = q.front(); - for (unsigned int i = 0; i < (g->adj[cur_node]).size(); ++i) { - int adj_node = (g->adj[cur_node])[i].first; - if (visited[adj_node] == false) { - visited[adj_node] = true; - min_dist_from_source[adj_node] = min_dist_from_source[cur_node] + 1; - q.push(adj_node); - } - } - q.pop(); - } - - return; - } - - void run(int sourcei, int sourcej){ - int source = (g->hash)(sourcei, sourcej); - run(source); - } - void run(int sourcei, int sourcej, int sourcek){ - int source = (g->hash)(sourcei, sourcej, sourcek); - run(source); - } - - int min_dist(int targeti, int targetj){ - int target = (g->hash)(targeti,targetj); - return min_dist_from_source[target]; - } - int min_dist(int targeti,int targetj,int targetk){ - int target = (g->hash)(targeti,targetj,targetk); - return min_dist_from_source[target]; - } - int min_dist(int target){ - return min_dist_from_source[target]; - } - - bool is_visisted(int targeti,int targetj){ - int target = (g->hash)(targeti,targetj); - return visited[target]; - } - bool is_visisted(int targeti,int targetj,int targetk){ - int target = (g->hash)(targeti,targetj,targetk); - return visited[target]; - } - bool is_visisted(int target){ - return visited[target]; - } - -}; -//END COPYING HERE -//********************BLACKBOX END****************** -int main() { - // initaitise a directed graph with 4 nodes, nodes are 0-indexed - Graph g(4, true); - // initaitise an un-directed graph with 4 nodes, nodes are 0-indexed - Graph g(4, false); - - //DIRECTED GRAPH : add edges `Node 0 -> Node 4` and `Node 1 -> Node 3` - g.add_edge(0,4); - g.add_edge(1,3); - - //UNDIRECT GRAPH : add edges between `Node 0 -- Node 4` and `Node 1 -- Node 3` - g.add_edge(0,4); - g.add_edge(1,3); - - //DIRECTED GRAPH 2D (useful for grid problems): add edges `Node {0,1} -> Node {2,4}` and `Node {3,1} -> Node {3,3}` - g.add_edge(0,1,2,4); - g.add_edge(3,1,3,1); - - //UNDIRECT GRAPH 2D (useful for grid problems): add edges between `Node {0,1} -- Node {2,4}` and `Node {3,1} -- Node {3,3}` - g.add_edge(0,1,2,4); - g.add_edge(3,1,3,1); - - - - - //*Do BFS on the graph g* - BFS bfs(&g); - - //BFS on 1D Graph - //start bfs on `Node 2` - bfs.run(2); - //get minimum distance of `Node 4` from source node (minimum distance is -1 if `Node 4` is unreacable from soure node) - int min_d = bfs.min_dist(4); - //check if `Node 4` is visited aka reachable from source node - bool is_reachable = bfs.is_visisted(4); - - - //BFS on 2D Graph - //start bfs on `Node {1,4}` - bfs.run(1,4); - //get minimum distance of `Node {2,3}` from source node (minimum distance is -1 if `Node {2,3}` is unreacable from soure node) - int min_d = bfs.min_dist(2,3); - //check if `Node {2,3}` is visited aka reachable from source node - bool is_reachable = bfs.is_visisted(2,3); - - - - return 0; -} - -/*NOTES -1. [IMP for P2 & P4] If you call bfs.run again (even with a different source node), the previous run's minimum distance and visited is maintained -2. The Nodes are 0-indexed. -*/ diff --git a/GraphX.cpp b/GraphX.cpp deleted file mode 100644 index b1c98a2..0000000 --- a/GraphX.cpp +++ /dev/null @@ -1,172 +0,0 @@ - -//COPY THE BLACKBOX, there is no need to change anything in it. -//Check the main function at bottom for USAGE - -//****************BLACKBOX START***************** -//START COPYING FROM HERE - -typedef int ll; - -class Hash { - private: - map,int>hash_table; - public: - Hash () {} - int hash(int x){ - return hash({x,0,0}); - } - int hash(tuplex){ - return hash({get<0>(x),get<1>(x),0}); - } - int hash(tuplex){ - if(hash_table.find(x)!=hash_table.end()) - return hash_table[x]; - int new_hash = hash_table.size(); - hash_table[x]=new_hash; - return new_hash; - } -}; - -class Graph { - - bool is_directed; - - public: - vector>>adj; - int n,N=5000000; - Hash h; - - Graph(int n_, bool is_directed_ = true){ - n=n_; is_directed = is_directed_; - adj.resize(N,vector>()); - } - - int hash(int u, int v){ - return h.hash({u,v}); - } - int hash(int u, int v, int k){ - return h.hash({u,v,k}); - } - - void add_edge(int uR, int vR, ll c=0){ - int u=h.hash(uR), v=h.hash(vR); - add_edge_internal(u,v,c); - } - void add_edge(tuple uR, tuple vR, ll c=0){ - int u=h.hash(uR), v=h.hash(vR); - add_edge_internal(u,v,c); - } - void add_edge(tuple uR, tuple vR, ll c=0){ - int u=h.hash(uR), v=h.hash(vR); - add_edge_internal(u,v,c); - } - - - private : - - void add_edge_internal(int u, int v, ll c=0){ - add_edge_weighted_undirected(u,v,c); - if(!is_directed) - add_edge_weighted_undirected(v,u,c); - } - void add_edge_weighted_undirected(int u, int v, ll c) { - pairp = make_pair(v,c); - adj[u].push_back(p); - } - -}; - -class BFS { - vectormin_dist_from_source; - vector visited; - Graph *g; - - public: - BFS(Graph *g_) { - g = g_; - clear(); - } - - void clear() { - min_dist_from_source.clear(); - min_dist_from_source.resize(g->N,-1); - visited.clear(); - visited.resize(g->N, false); - } - - - void run(int sourceR) { - int source = (g->h).hash(sourceR); - run_internal(source); - } - void run(tuple sourceR) { - int source = (g->h).hash(sourceR); - run_internal(source); - } - void run(tuple sourceR) { - int source = (g->h).hash(sourceR); - run_internal(source); - } - - - int min_dist(int targetR){ - int target = (g->h).hash(targetR); - return min_dist_internal(target); - } - int min_dist(tuple targetR){ - int target = (g->h).hash(targetR); - return min_dist_internal(target); - } - int min_dist(tuple targetR){ - int target = (g->h).hash(targetR); - return min_dist_internal(target); - } - - bool is_visited(int targetR){ - int target = (g->h).hash(targetR); - return is_visited_internal(target); - } - bool is_visited(tuple targetR){ - int target = (g->h).hash(targetR); - return is_visited_internal(target); - } - bool is_visited(tuple targetR){ - int target = (g->h).hash(targetR); - return is_visited_internal(target); - } - - private: - void run_internal(int source) { - queue q; - q.push(source); - - visited[source] = true; - min_dist_from_source[source] = 0; - - while(!q.empty()) { - int cur_node = q.front(); - for (unsigned int i = 0; i < (g->adj[cur_node]).size(); ++i) { - int adj_node = (g->adj[cur_node])[i].first; - if (visited[adj_node] == false) { - visited[adj_node] = true; - min_dist_from_source[adj_node] = min_dist_from_source[cur_node] + 1; - q.push(adj_node); - } - } - q.pop(); - } - - return; - } - - int min_dist_internal(int target){ - return min_dist_from_source[target]; - } - - bool is_visited_internal(int target){ - return visited[target]; - } - -}; -//END COPYING HERE -//********************BLACKBOX END****************** diff --git a/GraphX.java b/GraphX.java new file mode 100644 index 0000000..7c71f12 --- /dev/null +++ b/GraphX.java @@ -0,0 +1,270 @@ +import java.util.*; + +/** + * GraphX.java + * + * Complete Java port of the provided C++ GraphX "blackbox". + * - Hash maps int / pair / triple into a shared integer id space. + * - Graph supports addEdge for int/pair/triple keys. + * - BFS supports run(...) and query methods for min distance and visited. + * + * Note: Implementation uses lazy adjacency storage (HashMap) instead of preallocating + * a huge array to keep memory practical in Java while preserving behaviour. + */ +public class GraphX { + + /* ---------- Key classes for pair/triple semantics ---------- */ + + public static final class TripleKey { + public final int a, b, c; + public TripleKey(int a, int b, int c) { this.a = a; this.b = b; this.c = c; } + @Override public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TripleKey)) return false; + TripleKey t = (TripleKey) o; + return a == t.a && b == t.b && c == t.c; + } + @Override public int hashCode() { + int res = 17; + res = 31 * res + a; + res = 31 * res + b; + res = 31 * res + c; + return res; + } + @Override public String toString() { return "{" + a + "," + b + "," + c + "}"; } + } + + public static final class PairKey { + public final int a, b; + public PairKey(int a, int b) { this.a = a; this.b = b; } + public TripleKey toTriple() { return new TripleKey(a, b, 0); } + @Override public String toString() { return "(" + a + "," + b + ")"; } + } + + /* ---------- Hash (maps keys -> consecutive ints) ---------- */ + + public static final class Hash { + private final Map table = new HashMap<>(); + public Hash() {} + + // single int -> maps to triple (x,0,0) + public int hash(int x) { + return hash(new TripleKey(x, 0, 0)); + } + // pair -> maps to triple (a,b,0) + public int hash(PairKey p) { + return hash(p.toTriple()); + } + // triple -> canonical + public int hash(TripleKey t) { + Integer id = table.get(t); + if (id != null) return id; + int newId = table.size(); + table.put(t, newId); + return newId; + } + } + + /* ---------- adjacency pair (to, weight) ---------- */ + + public static final class AdjPair { + public final int to; + public final int weight; + public AdjPair(int to, int weight) { this.to = to; this.weight = weight; } + } + + /* ---------- Graph ---------- */ + + public static final class Graph { + private final boolean isDirected; + // lazy adjacency list: nodeId -> list of (neighbor, weight) + private final Map> adj; + public final int n; // user-provided n (kept for API consistency) + public final int N = 5_000_000; // kept as config constant (not forcibly allocated) + public final Hash h; + + public Graph(int n_) { this(n_, true); } + public Graph(int n_, boolean isDirected_) { + this.n = n_; + this.isDirected = isDirected_; + this.adj = new HashMap<>(); // lazy; more memory-friendly than preallocating N lists + this.h = new Hash(); + } + + // convenience: mirror C++ hash(u,v) & hash(u,v,k) + public int hash(int u, int v) { return h.hash(new TripleKey(u, v, 0)); } + public int hash(int u, int v, int k) { return h.hash(new TripleKey(u, v, k)); } + + // add edge overloads (int, PairKey, TripleKey). weight defaults to 0. + public void addEdge(int uR, int vR) { addEdge(uR, vR, 0); } + public void addEdge(int uR, int vR, int c) { + int u = h.hash(uR); + int v = h.hash(vR); + addEdgeInternal(u, v, c); + } + + public void addEdge(PairKey uR, PairKey vR) { addEdge(uR, vR, 0); } + public void addEdge(PairKey uR, PairKey vR, int c) { + int u = h.hash(uR); + int v = h.hash(vR); + addEdgeInternal(u, v, c); + } + + public void addEdge(TripleKey uR, TripleKey vR) { addEdge(uR, vR, 0); } + public void addEdge(TripleKey uR, TripleKey vR, int c) { + int u = h.hash(uR); + int v = h.hash(vR); + addEdgeInternal(u, v, c); + } + + // internal: add and possibly reverse if undirected (mirrors C++ behavior) + private void addEdgeInternal(int u, int v, int c) { + addEdgeWeighted(u, v, c); + if (!isDirected) { + addEdgeWeighted(v, u, c); + } + } + + private void addEdgeWeighted(int u, int v, int c) { + ArrayList list = adj.computeIfAbsent(u, k -> new ArrayList<>()); + list.add(new AdjPair(v, c)); + } + + // Accessors to adjacency for advanced usage/testing + public List neighborsOf(int hashedNode) { + return adj.getOrDefault(hashedNode, new ArrayList<>()); + } + } + + /* ---------- BFS ---------- */ + + public static final class BFS { + private final Map minDist; // node -> distance (unvisited absent -> -1) + private final Set visited; + private final Graph g; + + public BFS(Graph g_) { + this.g = g_; + this.minDist = new HashMap<>(); + this.visited = new HashSet<>(); + clear(); + } + + public void clear() { + minDist.clear(); + visited.clear(); + } + + // run overloads: int / PairKey / TripleKey + public void run(int sourceR) { + int source = g.h.hash(sourceR); + runInternal(source); + } + public void run(PairKey sourceR) { + int source = g.h.hash(sourceR); + runInternal(source); + } + public void run(TripleKey sourceR) { + int source = g.h.hash(sourceR); + runInternal(source); + } + + // minDist overloads + public int minDist(int targetR) { + int target = g.h.hash(targetR); + return minDistInternal(target); + } + public int minDist(PairKey targetR) { + int target = g.h.hash(targetR); + return minDistInternal(target); + } + public int minDist(TripleKey targetR) { + int target = g.h.hash(targetR); + return minDistInternal(target); + } + + // isVisited overloads + public boolean isVisited(int targetR) { + int target = g.h.hash(targetR); + return isVisitedInternal(target); + } + public boolean isVisited(PairKey targetR) { + int target = g.h.hash(targetR); + return isVisitedInternal(target); + } + public boolean isVisited(TripleKey targetR) { + int target = g.h.hash(targetR); + return isVisitedInternal(target); + } + + // BFS core (unweighted edges; distance measured in number of edges) + private void runInternal(int source) { + // reset + minDist.clear(); + visited.clear(); + + Queue q = new ArrayDeque<>(); + q.add(source); + visited.add(source); + minDist.put(source, 0); + + while (!q.isEmpty()) { + int cur = q.poll(); + int curDist = minDist.get(cur); + List neighbors = g.neighborsOf(cur); + for (AdjPair p : neighbors) { + int nxt = p.to; + if (!visited.contains(nxt)) { + visited.add(nxt); + minDist.put(nxt, curDist + 1); + q.add(nxt); + } + } + } + } + + private int minDistInternal(int target) { + return minDist.getOrDefault(target, -1); + } + private boolean isVisitedInternal(int target) { + return visited.contains(target); + } + } + + /* ---------- Example usage (main) ---------- */ + + public static void main(String[] args) { + // Simple example to show parity with the original blackbox usage. + // Create a small undirected graph and run BFS. + Graph g = new Graph(10, false); // undirected + // add edges using plain ints (these will be hashed internally) + g.addEdge(1, 2); + g.addEdge(2, 3); + g.addEdge(3, 4); + g.addEdge(10, 5); + + // add edges using PairKey + PairKey p1 = new PairKey(100, 200); + PairKey p2 = new PairKey(100, 201); + g.addEdge(p1, p2); + + // add edges using TripleKey + TripleKey t1 = new TripleKey(7, 8, 9); + TripleKey t2 = new TripleKey(7, 8, 10); + g.addEdge(t1, t2); + + BFS bfs = new BFS(g); + bfs.run(1); + System.out.println("dist(1->2) = " + bfs.minDist(2)); // should be 1 + System.out.println("dist(1->4) = " + bfs.minDist(4)); // should be 3 + System.out.println("visited(4) = " + bfs.isVisited(4)); + + // BFS from a PairKey node + bfs.run(p1); + System.out.println("dist(pair p1 -> p2) = " + bfs.minDist(p2)); + + // BFS from a triple node + bfs.run(t1); + System.out.println("dist(triple t1 -> t2) = " + bfs.minDist(t2)); + } +} diff --git a/HLD.cpp b/HLD.cpp deleted file mode 100644 index 8cd4a3e..0000000 --- a/HLD.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include -#include -using namespace std; - -#define root 0 -#define N 10100 -#define LN 14 - -vector adj[N], costs[N], indexx[N]; -int baseArray[N], ptr; -int chainNo, chainInd[N], chainHead[N], posInBase[N]; -int depth[N], pa[LN][N], otherEnd[N], subsize[N]; -int st[N*6], qt[N*6]; - -/* - * make_tree: - * Used to construct the segment tree. It uses the baseArray for construction - */ -void make_tree(int cur, int s, int e) { - if(s == e-1) { - st[cur] = baseArray[s]; - return; - } - int c1 = (cur<<1), c2 = c1 | 1, m = (s+e)>>1; - make_tree(c1, s, m); - make_tree(c2, m, e); - st[cur] = st[c1] > st[c2] ? st[c1] : st[c2]; -} - -/* - * update_tree: - * Point update. Update a single element of the segment tree. - */ -void update_tree(int cur, int s, int e, int x, int val) { - if(s > x || e <= x) return; - if(s == x && s == e-1) { - st[cur] = val; - return; - } - int c1 = (cur<<1), c2 = c1 | 1, m = (s+e)>>1; - update_tree(c1, s, m, x, val); - update_tree(c2, m, e, x, val); - st[cur] = st[c1] > st[c2] ? st[c1] : st[c2]; -} - -/* - * query_tree: - * Given S and E, it will return the maximum value in the range [S,E) - */ -void query_tree(int cur, int s, int e, int S, int E) { - if(s >= E || e <= S) { - qt[cur] = -1; - return; - } - if(s >= S && e <= E) { - qt[cur] = st[cur]; - return; - } - int c1 = (cur<<1), c2 = c1 | 1, m = (s+e)>>1; - query_tree(c1, s, m, S, E); - query_tree(c2, m, e, S, E); - qt[cur] = qt[c1] > qt[c2] ? qt[c1] : qt[c2]; -} - -/* - * query_up: - * It takes two nodes u and v, condition is that v is an ancestor of u - * We query the chain in which u is present till chain head, then move to next chain up - * We do that way till u and v are in the same chain, we query for that part of chain and break - */ - -int query_up(int u, int v) { - if(u == v) return 0; // Trivial - int uchain, vchain = chainInd[v], ans = -1; - // uchain and vchain are chain numbers of u and v - while(1) { - uchain = chainInd[u]; - if(uchain == vchain) { - // Both u and v are in the same chain, so we need to query from u to v, update answer and break. - // We break because we came from u up till v, we are done - if(u==v) break; - query_tree(1, 0, ptr, posInBase[v]+1, posInBase[u]+1); - // Above is call to segment tree query function - if(qt[1] > ans) ans = qt[1]; // Update answer - break; - } - query_tree(1, 0, ptr, posInBase[chainHead[uchain]], posInBase[u]+1); - // Above is call to segment tree query function. We do from chainHead of u till u. That is the whole chain from - // start till head. We then update the answer - if(qt[1] > ans) ans = qt[1]; - u = chainHead[uchain]; // move u to u's chainHead - u = pa[0][u]; //Then move to its parent, that means we changed chains - } - return ans; -} - -/* - * LCA: - * Takes two nodes u, v and returns Lowest Common Ancestor of u, v - */ -int LCA(int u, int v) { - if(depth[u] < depth[v]) swap(u,v); - int diff = depth[u] - depth[v]; - for(int i=0; i>i)&1 ) u = pa[i][u]; - if(u == v) return u; - for(int i=LN-1; i>=0; i--) if(pa[i][u] != pa[i][v]) { - u = pa[i][u]; - v = pa[i][v]; - } - return pa[0][u]; -} - -void query(int u, int v) { - /* - * We have a query from u to v, we break it into two queries, u to LCA(u,v) and LCA(u,v) to v - */ - int lca = LCA(u, v); - int ans = query_up(u, lca); // One part of path - int temp = query_up(v, lca); // another part of path - if(temp > ans) ans = temp; // take the maximum of both paths - printf("%d\n", ans); -} - -/* - * change: - * We just need to find its position in segment tree and update it - */ -void change(int i, int val) { - int u = otherEnd[i]; - update_tree(1, 0, ptr, posInBase[u], val); -} - -/* - * Actual HL-Decomposition part - * Initially all entries of chainHead[] are set to -1. - * So when ever a new chain is started, chain head is correctly assigned. - * As we add a new node to chain, we will note its position in the baseArray. - * In the first for loop we find the child node which has maximum sub-tree size. - * The following if condition is failed for leaf nodes. - * When the if condition passes, we expand the chain to special child. - * In the second for loop we recursively call the function on all normal nodes. - * chainNo++ ensures that we are creating a new chain for each normal child. - */ -void HLD(int curNode, int cost, int prev) { - if(chainHead[chainNo] == -1) { - chainHead[chainNo] = curNode; // Assign chain head - } - chainInd[curNode] = chainNo; - posInBase[curNode] = ptr; // Position of this node in baseArray which we will use in Segtree - baseArray[ptr++] = cost; - - int sc = -1, ncost; - // Loop to find special child - for(int i=0; i::max(); -struct point {// point structure for 2D-tree, can be extended to 3D - ntype x, y; - point(ntype xx = 0, ntype yy = 0) : x(xx), y(yy) {} -}; -bool operator==(const point &a, const point &b) {return a.x == b.x && a.y == b.y;} -bool on_x(const point &a, const point &b) {return a.x < b.x;} // sorts points on x-coordinate -bool on_y(const point &a, const point &b) {return a.y < b.y;} // sorts points on y-coordinate -ntype pdist2(const point &a, const point &b) {ntype dx = a.x-b.x, dy = a.y-b.y;return dx*dx + dy*dy;}// squared distance between points - -struct bbox{// bounding box for a set of points - ntype x0, x1, y0, y1; - bbox() : x0(sentry), x1(-sentry), y0(sentry), y1(-sentry) {} - void compute(const vector &v) {// computes bounding box from a bunch of points - for (int i = 0; i < v.size(); ++i) { - x0 = min(x0, v[i].x); x1 = max(x1, v[i].x); - y0 = min(y0, v[i].y); y1 = max(y1, v[i].y); - } - } - ntype distance(const point &p) {// squared distance between a point and this bbox, 0 if inside - if (p.x < x0) { - if (p.y < y0) return pdist2(point(x0, y0), p); - else if (p.y > y1) return pdist2(point(x0, y1), p); - else return pdist2(point(x0, p.y), p); - } - else if (p.x > x1) { - if (p.y < y0) return pdist2(point(x1, y0), p); - else if (p.y > y1) return pdist2(point(x1, y1), p); - else return pdist2(point(x1, p.y), p); - } - else { - if (p.y < y0) return pdist2(point(p.x, y0), p); - else if (p.y > y1) return pdist2(point(p.x, y1), p); - else return 0; - } - } -}; -struct kdnode {// stores a single node of the kd-tree, either internal or leaf - bool leaf; // true if this is a leaf node (has one point) - point pt; // the single point of this is a leaf - bbox bound; // bounding box for set of points in children - kdnode *first, *second; // two children of this kd-node - kdnode() : leaf(false), first(0), second(0) {} - ~kdnode() { if (first) delete first; if (second) delete second; } - ntype intersect(const point &p) {return bound.distance(p);}// intersect a point with this node (returns squared distance) - void construct(vector &vp){ // recursively builds a kd-tree f1rom a given cloud of points - bound.compute(vp); // compute bounding box for points at this node - if (vp.size() == 1) {// if we're down to one point, then we're a leaf node - leaf = true; - pt = vp[0]; - } - else { - // split on x if the bbox is wider than high (not best heuristic...) else // otherwise split on y-coordinate - if (bound.x1-bound.x0 >= bound.y1-bound.y0) sort(vp.begin(), vp.end(), on_x); else sort(vp.begin(), vp.end(), on_y); - // divide by taking half the array for each child(not best performance if many duplicates in the middle) - int half = vp.size()/2; - vector vl(vp.begin(), vp.begin()+half); - vector vr(vp.begin()+half, vp.end()); - first = new kdnode(); first->construct(vl); - second = new kdnode(); second->construct(vr); - } - } -}; -struct kdtree{// simple kd-tree class to hold the tree and handle queries - kdnode *root; - kdtree(const vector &vp) {// constructs a kd-tree from a points (copied here, as it sorts them) - vector v(vp.begin(), vp.end()); - root = new kdnode(); - root->construct(v); - } - ~kdtree() { delete root; } - // recursive search method returns squared distance to nearest point - ntype search(kdnode *node, const point &p){ - if (node->leaf) { - // commented special case tells a point not to find itself -// if (p == node->pt) return sentry; -// else - return pdist2(p, node->pt); - } - ntype bfirst = node->first->intersect(p); - ntype bsecond = node->second->intersect(p); - // choose the side with the closest bounding box to search first - // (note that the other side is also searched if needed) - if (bfirst < bsecond) { - ntype best = search(node->first, p); - if (bsecond < best) best = min(best, search(node->second, p)); - return best; - } else { - ntype best = search(node->second, p); - if (bfirst < best) best = min(best, search(node->first, p)); - return best; - } - } - // squared distance to the nearest - ntype nearest(const point &p) {return search(root, p);} -}; -int main() {// some basic test code here - vector vp;// generate some random points for a kd-tree - for (int i = 0; i < 100000; ++i) vp.push_back(point(rand()%100000, rand()%100000)); - kdtree tree(vp); - for (int i = 0; i < 10; ++i) {// query some points - point q(rand()%100000, rand()%100000); - cout<<"Closest squared distance to (" << q.x << ", " << q.y << ")"<< " is " << tree.nearest(q) << endl; - } -} diff --git a/Matrix Determinant.cpp b/Matrix Determinant.cpp deleted file mode 100644 index a523574..0000000 --- a/Matrix Determinant.cpp +++ /dev/null @@ -1,19 +0,0 @@ -//N^3, can remove mods -const ll mod = 12345; -ll det(vector>& a) { - int n = sz(a); ll ans = 1; - rep(i,0,n) { - rep(j,i+1,n) { - while (a[j][i] != 0) { // gcd step - ll t = a[i][i] / a[j][i]; - if (t) rep(k,i,n) - a[i][k] = (a[i][k] - a[j][k] * t) % mod; - swap(a[i], a[j]); - ans *= -1; - } - } - ans = ans * a[i][i] % mod; - if (!ans) return 0; - } - return (ans + mod) % mod; -} diff --git a/Matrix Expo.cpp b/Matrix Expo.cpp deleted file mode 100644 index d78876a..0000000 --- a/Matrix Expo.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* -Uses powers of two to exponentiate numbers and matrices. Calculates -n^k in O(log(k)) time when n is a number. If A is an n x n matrix, -calculates A^k in O(n^3*log(k)) time. -*/ -#include -using namespace std; -typedef double T; -typedef vector VT; -typedef vector VVT; -T power(T x, int k) { - T ret = 1; - while(k) { - if(k & 1) ret *= x; - k >>= 1; x *= x; - } - return ret; -} -VVT multiply(VVT& A, VVT& B) { - int n = A.size(), m = A[0].size(), k = B[0].size(); - VVT C(n, VT(k, 0)); - - for(int i = 0; i < n; i++) - for(int j = 0; j < k; j++) - for(int l = 0; l < m; l++) - C[i][j] += A[i][l] * B[l][j]; - - return C; -} -VVT power(VVT& A, int k) { - int n = A.size(); - VVT ret(n, VT(n)), B = A; - for(int i = 0; i < n; i++) ret[i][i]=1; - while(k) { - if(k & 1) ret = multiply(ret, B); - k >>= 1; B = multiply(B, B); - } - return ret; -} -int main() { - /* Expected Output: - 2.37^48 = 9.72569e+17 - 376 264 285 220 265 - 550 376 529 285 484 - 484 265 376 264 285 - 285 220 265 156 264 - 529 285 484 265 376 */ - double n = 2.37; int k = 48; - cout << n << "^" << k << " = " << power(n, k) << endl; - double At[5][5] = { - { 0, 0, 1, 0, 0 }, - { 1, 0, 0, 1, 0 }, - { 0, 0, 0, 0, 1 }, - { 1, 0, 0, 0, 0 }, - { 0, 1, 0, 0, 0 } }; - - vector > A(5, vector (5)); - for(int i = 0; i < 5; i++) - for(int j = 0; j < 5; j++) - A[i][j] = At[i][j]; - - vector > Ap = power(A, k); - - cout << endl; - for(int i = 0; i < 5; i++) { - for(int j = 0; j < 5; j++) - cout << Ap[i][j] << " "; - cout << endl; - } -} diff --git a/Miller Rabin + mod_Mull.cpp b/Miller Rabin + mod_Mull.cpp deleted file mode 100644 index 495e982..0000000 --- a/Miller Rabin + mod_Mull.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*Miller-Rabin primality probabilistic test. - * Probability of failing one iteration is at most 1/4. 15 iterations should be enough for 50-bit numbers. - * Time: 15 times the complexity of $a^b \mod c$. */ - - typedef unsigned long long ull; -const int bits = 10; -// if all numbers are less than 2^k, set bits = 64-k -const ull po = 1 << bits; -ull mod_mul(ull a, ull b, ull &c) { - ull x = a * (b & (po - 1)) % c; - while ((b >>= bits) > 0) { - a = (a << bits) % c; - x += (a * (b & (po - 1))) % c; - } - return x % c; -} -ull mod_pow(ull a, ull b, ull mod) { - if (b == 0) return 1; - ull res = mod_pow(a, b / 2, mod); - res = mod_mul(res, res, mod); - if (b & 1) return mod_mul(res, a, mod); - return res; -} -bool prime(ull p) { //Rabin Miller - if (p == 2) return true; - if (p == 1 || p % 2 == 0) return false; - ull s = p - 1; - while (s % 2 == 0) s /= 2; - rep(i,0,15) { - ull a = rand() % (p - 1) + 1, tmp = s; - ull mod = mod_pow(a, tmp, p); - while (tmp != p - 1 && mod != 1 && mod != p - 1) { - mod = mod_mul(mod, mod, p); - tmp *= 2; - } - if (mod != p - 1 && tmp % 2 == 0) return false; - } - return true; -} diff --git a/Min Vertex Cover.cpp b/Min Vertex Cover.cpp deleted file mode 100644 index eee44fa..0000000 --- a/Min Vertex Cover.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* Description: Finds a minimum vertex cover in a bipartite graph. - * The size is the same as the size of a maximum matching, and - * the complement is an independent set. - * Status: fuzz-tested - */ -#pragma once - -#include "DFSMatching.h" - -vi cover(vector& g, int n, int m) { - int res = dfs_matching(g, n, m); - seen.assign(m, false); - vector lfound(n, true); - trav(it, match) if (it != -1) lfound[it] = false; - vi q, cover; - rep(i,0,n) if (lfound[i]) q.push_back(i); - while (!q.empty()) { - int i = q.back(); q.pop_back(); - lfound[i] = 1; - trav(e, g[i]) if (!seen[e] && match[e] != -1) { - seen[e] = true; - q.push_back(match[e]); - } - } - rep(i,0,n) if (!lfound[i]) cover.push_back(i); - rep(i,0,m) if (seen[i]) cover.push_back(n+i); - assert(sz(cover) == res); - return cover; -} diff --git a/MinCostMaxFlow.cpp b/MinCostMaxFlow.cpp deleted file mode 100644 index 4449dc1..0000000 --- a/MinCostMaxFlow.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* Min-cost max-flow. cap[i][j] != cap[j][i] is allowed; double edges are not. - * If costs can be negative, call setpi before maxflow, but note that negative cost cycles are not supported. - * To obtain the actual flow, look at positive values only. Time: Approximately O(E^2) */ -/*INPUT: - graph, constructed using AddEdge() -// - source -// - sink -// OUTPUT: - (maximum flow value, minimum cost value) -// - To obtain the actual flow, look at positive values only*/ -#include /** keep-include */ -const ll INF = numeric_limits::max() / 4; typedef vector VL; -struct MCMF { - int N; - vector ed, red; - vector cap, flow, cost; - vi seen; - VL dist, pi; - vector par; - MCMF(int N) : - N(N), ed(N), red(N), cap(N, VL(N)), flow(cap), cost(cap), - seen(N), dist(N), pi(N), par(N) {} - void addEdge(int from, int to, ll cap, ll cost) { - this->cap[from][to] = cap; - this->cost[from][to] = cost; - ed[from].push_back(to); - red[to].push_back(from); - } - void path(int s) { - fill(all(seen), 0); - fill(all(dist), INF); - dist[s] = 0; ll di; - __gnu_pbds::priority_queue> q; - vector its(N); - q.push({0, s}); - auto relax = [&](int i, ll cap, ll cost, int dir) { - ll val = di - pi[i] + cost; - if (cap && val < dist[i]) { - dist[i] = val; - par[i] = {s, dir}; - if (its[i] == q.end()) its[i] = q.push({-dist[i], i}); - else q.modify(its[i], {-dist[i], i}); - } - }; - while (!q.empty()) { - s = q.top().second; q.pop(); - seen[s] = 1; di = dist[s] + pi[s]; - trav(i, ed[s]) if (!seen[i]) relax(i, cap[s][i] - flow[s][i], cost[s][i], 1); - trav(i, red[s]) if (!seen[i]) relax(i, flow[i][s], -cost[i][s], 0); - } - rep(i,0,N) pi[i] = min(pi[i] + dist[i], INF); - } - pair maxflow(int s, int t) { - ll totflow = 0, totcost = 0; - while (path(s), seen[t]) { - ll fl = INF; - for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p) fl = min(fl, r ? cap[p][x] - flow[p][x] : flow[x][p]); - totflow += fl; - for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p) if (r) flow[p][x] += fl; else flow[x][p] -= fl; - } - rep(i,0,N) rep(j,0,N) totcost += cost[i][j] * flow[i][j]; - return {totflow, totcost}; - } // If some costs can be negative, call this[setpi()] before maxflow: - void setpi(int s) { // (otherwise, leave this out) - fill(all(pi), INF); pi[s] = 0; - int it = N, ch = 1; ll v; - while (ch-- && it--) rep(i,0,N) if (pi[i] != INF) trav(to, ed[i]) if (cap[i][to]) - if ((v = pi[i] + cost[i][to]) < pi[to]) pi[to] = v, ch = 1; - assert(it >= 0); // negative cost cycle - } -}; diff --git a/NTT.cpp b/NTT.cpp deleted file mode 100644 index c31a8ea..0000000 --- a/NTT.cpp +++ /dev/null @@ -1,59 +0,0 @@ - -// If p=c.2^k+1, then we need 2^k th root of unity -// root= not generator, rather g^c , root of unity, root_1 is its inverse wrt mod, root_pw means 2^k -// inverse(n,mod) is a function for modular inverse\ -// for fft with arbitrary remainder, break coefficients into modulo sqrt(M), dont use CRT -const int mod = 7340033; -const int root = 5; -const int root_1 = 4404020; -const int root_pw = 1 << 20; - -void fft(vector & a, bool invert) { - int n = a.size(); - - for (int i = 1, j = 0; i < n; i++) { - int bit = n >> 1; - for (; j & bit; bit >>= 1) - j ^= bit; - j ^= bit; - - if (i < j) - swap(a[i], a[j]); - } - for (int len = 2; len <= n; len <<= 1) { - int wlen = invert ? root_1 : root; - for (int i = len; i < root_pw; i <<= 1) - wlen = (int)(1LL * wlen * wlen % mod); - - for (int i = 0; i < n; i += len) { - int w = 1; - for (int j = 0; j < len / 2; j++) { - int u = a[i+j], v = (int)(1LL * a[i+j+len/2] * w % mod); - a[i+j] = u + v < mod ? u + v : u + v - mod; - a[i+j+len/2] = u - v >= 0 ? u - v : u - v + mod; - w = (int)(1LL * w * wlen % mod); - } - } - } - if (invert) { - int n_1 = inverse(n, mod); - for (int & x : a) - x = (int)(1LL * x * n_1 % mod); - } -} -vector multiply(vector const& a, vector const& b) { - vector fa(a),fb(b) ; - int n = 1; - while (n < a.size() + b.size()) - n <<= 1; - fa.resize(n); - fb.resize(n); - - fft(fa, false); - fft(fb, false); - for (int i = 0; i < n; i++) - fa[i] = (fa[i]*1LL*fb[i])%mod; - fft(fa, true); - fa.resize(a.size()+b.size()-1) ; - return fa; -} diff --git a/Neeraj_FFT.cpp b/Neeraj_FFT.cpp deleted file mode 100644 index df0109f..0000000 --- a/Neeraj_FFT.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#pragma GCC target("popcnt") -#pragma GCC optimize("tree-vectorize") -#include -using namespace std; -unsigned long long a[64][3300], b[64][3300]; -string s1, s2; -int main(){ - cin >> s1 >> s2; - for (int i = 0; i < s1.size(); i++) { - if (s1[i] == '0') continue; - for (int j = 0; j < 64; j++) { - if (i < j) continue; - a[j][(i - j) / 64] |= 1ULL << (i - j) % 64; - } - } - for (int i = 0; i < s2.size(); i++){ - if (s2[i] == '0') continue; - for (int j = 0; j < 64; j++) { - if (i < j) continue; - b[j][(i - j) / 64] |= 1ULL << (i - j) % 64; - } - } - int q;cin >> q; - while (q--) { - unsigned p1, p2, len; - cin >> p1 >> p2 >> len; - int ans = 0; - for (size_t i = 0; i < len / 64; i++) - ans += __builtin_popcountll(a[p1 % 64][p1 / 64 + i] ^ b[p2 % 64][p2 / 64 + i]); - for (size_t i = len / 64 * 64; i < len; i++) ans += s1[p1 + i] ^ s2[p2 + i]; - printf("%d\n", ans); - } -} -/////////////longest common substring+LCP_FUN///// -#define f first -#define s second -int suf[500005],sar[500005][20],lcp[500005],lev=1,mul=1,n; -int lcp_fun(int x,int y) { int ans=0; - for(int k=lev-1;k>=0&&x,int> > ve; - string s,v; - cin>>s>>v; - m = v.size(); - s.pb('z'+1); - for(i=0;i1) st++,cn1--; - while(st= m && cn2>1) st++,cnt2--; - // cout<0 && dist[to[e]]==-1){ - q[tail] = to[e]; ++tail; - dist[to[e]] = dist[v]+1; - } - } - } - return dist[s]!=-1; - } - int dfs(int v, int f){ - if(v==t) return f; - for(int &e = now[v];e!=-1;e = next[e]){ - if(cap[e]>0 && dist[to[e]]==dist[v]-1){ - int ret = dfs(to[e],min(f,cap[e])); - if(ret>0){ - cap[e] -= ret; - cap[e^1] += ret; - return ret; - } - } - } - return 0; - } - long long max_flow(int source, int sink){ - s = source; t = sink; - long long f = 0; - int x; - while(bfs()){ - for(int i = 0;i > initial_cap, cap; - vector vis, where; - SimpleMaxFlow(int _n) { - n = _n + 1; - initial_cap = vector >(n, vector(n)); - cap = vector >(n, vector(n)); - } - void addEdge(int a, int b, int c) {initial_cap[a][b] = cap[a][b] = c;} - int dfs(int x, int f) { - if(vis[x]) return 0; - if(x == t) return f; - vis[x] = 1; - int ret = 0; - for(int i = 0; i < n; ++i) if(!vis[i] && cap[x][i] > 0) { - where[i] = x; - ret = max(ret, dfs(i, min(f, cap[x][i]))); - } - return ret; - } - int dfs_aug() { - vis = vector(n, 0); - where = vector(n, -1); - return dfs(s, oo); - } - int bfs_aug() { - vis = vector(n, 0); - where = vector(n, -1); - queue > q; - q.push(make_pair(s, oo)); - vis[s] = 1; - while(!q.empty()) { - pair cur = q.front(); q.pop(); - if(cur.fi == t) return cur.se; - vis[cur.fi] = 1; - for(int i = 0; i < n; ++i) if(cap[cur.fi][i] > 0 && !vis[i]) { - where[i] = cur.fi; - vis[i] = 1; - q.push(make_pair(i, min(cur.se, cap[cur.fi][i]))); - } - } return 0; - } - int pfs_aug() { - vis = vector(n, 0); - where = vector(n, -1); - priority_queue > pq; - pq.push(make_pair(s, oo)); - vis[s] = 1; - while(!pq.empty()) { - pair cur = pq.top(); pq.pop(); - if(cur.fi == t) return cur.se; - vis[cur.fi] = 1; - for(int i = 0; i < n; ++i) if(cap[cur.fi][i] > 0 && !vis[i]) { - where[i] = cur.fi; - vis[i] = 1; - pq.push(make_pair(i, min(cur.se, cap[cur.fi][i]))); - } - } return 0; - } - int flow(int _s, int _t) { - s = _s; t = _t; int f = 0; - while(int inc = pfs_aug()) { - f += inc; - int cur = t; - while(where[cur] > -1) { - cap[where[cur]][cur] -= inc; - cap[cur][where[cur]] += inc; - cur = where[cur]; - } - } return f; - } - /*void disp() { - cerr << endl<< "Flow from " << s << " to " << t << endl; - for(int i = 0; i < n; ++i) for(int j = 0; j < n; ++j) if(initial_cap[i][j] > 0) {cerr << i << " " << j << " " << cap[i][j] << "/" << initial_cap[i][j] << endl;} - cerr << endl; - }*/}; -typedef vector vi; //////////////[HOPCRAFT]//////////////////// -#define all(x) x.begin(), x.end() -#define trav(a, x) for(auto& a : x) -#define rep(i, a, b) for(int i = a; i < (b); ++i) -#define sz(x) (int)(x).size() -bool dfs_(int a,int layer,const vector& g,vi& btoa,vi& A,vi& B) { - if (A[a] != layer) return 0; A[a] = -1; - trav(b, g[a]) if (B[b] == layer + 1) {B[b] = -1; - if (btoa[b]==-1 || dfs_(btoa[b],layer+2,g,btoa,A,B)) return btoa[b]=a,1;} - return 0; -} -int hopcroftKarp(const vector& g, vi& btoa) { - int res=0;vi A(g.size()), B(btoa.size()), cur, next; - for (;;) { - fill(all(A), 0); fill(all(B), -1); - cur.clear();/// Find the starting nodes for BFS (i.e. layer 0). - trav(a, btoa) if(a != -1) A[a] = -1; - rep(a,0,sz(g)) if(A[a] == 0) cur.push_back(a); - for (int lay=1;;lay+=2) {/// Find all layers using bfs. - bool islast = 0;next.clear(); - trav(a, cur) trav(b, g[a]) { - if (btoa[b]==-1) B[b]=lay,islast=1; - else if (btoa[b]!=a && B[b]==-1) B[b]=lay,next.push_back(btoa[b]); - } - if (islast) break; if (next.empty()) return res; - trav(a,next) A[a]=lay+1; cur.swap(next); - }/// Use dfs_ to scan for augmenting paths. - rep(a,0,sz(g)) if(dfs_(a, 0, g, btoa, A, B)) ++res; - } -} diff --git a/Policy BST.cpp b/Policy BST.cpp deleted file mode 100644 index 2b98933..0000000 --- a/Policy BST.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include // Common file -#include // Including tree_order_statistics_node_update -using namespace __gnu_pbds; -struct cmp { - bool operator() (const int& a, const int& b) const { - return a T; - -T.find_by_order(k); // iterator to the k-th largest element (counting from zero) -T.order_of_key(x); // no of elements strictly smaller than x diff --git a/Pollard Rho- Factors.cpp b/Pollard Rho- Factors.cpp deleted file mode 100644 index 465cabc..0000000 --- a/Pollard Rho- Factors.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/*Pollard's rho algorithm. It is a probabilistic factorisation - * algorithm, whose expected time complexity is good. Before you start using it, - * run {\tt init(bits)}, where bits is the length of the numbers you use. - * Returns factors of the input without duplicates. - * Time: Expected running time should be good enough for 50-bit numbers. - */ -#include "ModMulLL.h" -#include "MillerRabin.h" -#include "eratosthenes.h" -vector pr; -ull f(ull a, ull n, ull &has) { - return (mod_mul(a, a, n) + has) % n; -} -vector factor(ull d) { - vector res; - for (int i = 0; i < sz(pr) && pr[i]*pr[i] <= d; i++) - if (d % pr[i] == 0) { - while (d % pr[i] == 0) d /= pr[i]; - res.push_back(pr[i]); - } - //d is now a product of at most 2 primes. - if (d > 1) { - if (prime(d)) - res.push_back(d); - else while (true) { - ull has = rand() % 2321 + 47; - ull x = 2, y = 2, c = 1; - for (; c==1; c = __gcd((y > x ? y - x : x - y), d)) { - x = f(x, d, has); - y = f(f(y, d, has), d, has); - } - if (c != d) { - res.push_back(c); d /= c; - if (d != c) res.push_back(d); - break; - } - } - } - return res; -} -void init(int bits) {//how many bits do we use? - vi p = eratosthenes_sieve(1 << ((bits + 2) / 3)); - pr.assign(all(p)); -} diff --git a/README.md b/README.md deleted file mode 100644 index 76c6715..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# Algorithms-Notebook \ No newline at end of file diff --git a/RabinKarp String Hash.cpp b/RabinKarp String Hash.cpp deleted file mode 100644 index 0c49172..0000000 --- a/RabinKarp String Hash.cpp +++ /dev/null @@ -1,29 +0,0 @@ -struct Hashs -{ - vector hashs; - vector pows; - int P; - int MOD; - - Hashs() {} - - Hashs(string &s, int P, int MOD) : P(P), MOD(MOD) - { - int n = s.size(); - pows.resize(n+1, 0); - hashs.resize(n+1, 0); - pows[0] = 1; - for(int i=n-1;i>=0;i--) - { - hashs[i]=(1LL * hashs[i+1] * P + s[i] - 'a' + 1) % MOD; - pows[n-i]=(1LL * pows[n-i-1] * P) % MOD; - } - pows[n] = (1LL * pows[n-1] * P)%MOD; - } - int get_hash(int l, int r) - { - int ans=hashs[l] + MOD - (1LL*hashs[r+1]*pows[r-l+1])%MOD; - ans%=MOD; - return ans; - } -}; diff --git a/Sieve with logN factor queries.cpp b/Sieve with logN factor queries.cpp deleted file mode 100644 index 9450dd3..0000000 --- a/Sieve with logN factor queries.cpp +++ /dev/null @@ -1,24 +0,0 @@ -int lp [ 1000010 ] ; -vector < int > pr ; -void sieve(int N) { - for ( int i = 2 ; i <= N ; ++ i ) { - if ( lp [ i ] == 0 ) { - lp [ i ] = i ; - pr. push_back ( i ) ; - } - for ( int j = 0 ; j < ( int ) pr. size ( ) && pr [ j ] <= lp [ i ] && i * pr [ j ] <= N ; ++ j ) - lp [ i * pr [ j ] ] = pr [ j ] ; - } -} - -void factorquery(int x) { - cout<1 && x%y==0) x/=y; - if (x<2) return; - factorquery(x); -} - - -// sieve( N ); N<=10^7. Using lp[] we can prime factorize nos <=10^7 in O(log N) instead of usual O(sqrt(N)). diff --git a/SimpleGraphTemplate.cpp b/SimpleGraphTemplate.cpp deleted file mode 100644 index e098966..0000000 --- a/SimpleGraphTemplate.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include - -using namespace std; - -template -class Graph { -private: - vector> adj_list; - bool directed; - -public: - Graph(int n, bool is_directed = false) : adj_list(n), directed(is_directed) {} - - void add_edge(const T& u, const T& v) { - adj_list[u].push_back(v); - if (!directed) { - adj_list[v].push_back(u); - } - } - - vector bfs(const T& start, const vector& landmines) { - vector distance(adj_list.size(), -1); - distance[start] = 0; - - queue q; - q.push(start); - - while (!q.empty()) { - T current_node = q.front(); - q.pop(); - - for (const T& neighbor : adj_list[current_node]) { - if (distance[neighbor] == -1 && !landmines[neighbor]) { - distance[neighbor] = distance[current_node] + 1; - q.push(neighbor); - } - } - } - - return distance; - } -}; - -int main() { - int N, M; - cin >> N >> M; - - int source, target; - cin >> source >> target; - - vector landmines(N); - for (int i = 0; i < N; ++i) { - int has_landmine; - cin >> has_landmine; - landmines[i] = (has_landmine == 1); - } - - Graph g(N, false); // Undirected graph - - for (int i = 0; i < M; ++i) { - int u, v; - cin >> u >> v; - g.add_edge(u, v); - } - - vector distances = g.bfs(source, landmines); - - cout << distances[target] << "\n"; - - return 0; -} diff --git a/SimpleGraphTemplate.java b/SimpleGraphTemplate.java deleted file mode 100644 index 97d88c4..0000000 --- a/SimpleGraphTemplate.java +++ /dev/null @@ -1,133 +0,0 @@ -import java.io.*; -import java.util.*; - -public class GraphTemplate { - static class FastReader { - private final InputStream in; - private final byte[] buffer = new byte[1024]; - private int ptr = 0; - private int buflen = 0; - - public FastReader() { - in = System.in; - } - - private boolean hasNextByte() { - if (ptr < buflen) { - return true; - } else { - ptr = 0; - try { - buflen = in.read(buffer); - } catch (IOException e) { - e.printStackTrace(); - } - return buflen > 0; - } - } - - private int readByte() { - return hasNextByte() ? buffer[ptr++] : -1; - } - - private boolean isWhiteSpace(int c) { - return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1; - } - - public int nextInt() { - int n = 0; - boolean minus = false; - int c; - while ((c = readByte()) != -1 && isWhiteSpace(c)); - if (c == '-') { - minus = true; - c = readByte(); - } - do { - n = n * 10 + (c - '0'); - } while ((c = readByte()) >= '0' && c <= '9'); - return minus ? -n : n; - } - - public String next() { - StringBuilder sb = new StringBuilder(); - int c; - while ((c = readByte()) != -1 && isWhiteSpace(c)); - do { - sb.appendCodePoint(c); - } while ((c = readByte()) != -1 && !isWhiteSpace(c)); - return sb.toString(); - } - } - - static class Graph { - private final List> adjList; - private final int V; - - public Graph(int vertices) { - this.V = vertices; - adjList = new ArrayList<>(V); - for (int i = 0; i < V; i++) { - adjList.add(new ArrayList<>()); - } - } - - public void addEdge(int u, int v) { - adjList.get(u).add(v); - adjList.get(v).add(u); // Remove this line for directed graphs - } - - // Returns an array with the shortest distances from the start node to all other nodes - public int[] bfs(int start) { - boolean[] visited = new boolean[V]; - int[] distance = new int[V]; - Arrays.fill(distance, -1); // -1 indicates that the node is not reachable - - Queue queue = new LinkedList<>(); - queue.offer(start); - visited[start] = true; - distance[start] = 0; - - while (!queue.isEmpty()) { - int current = queue.poll(); - - for (int neighbor : adjList.get(current)) { - if (!visited[neighbor]) { - visited[neighbor] = true; - distance[neighbor] = distance[current] + 1; - queue.offer(neighbor); - } - } - } - - return distance; - } - } - - public static void main(String[] args) { - FastReader fr = new FastReader(); - PrintWriter out = new PrintWriter(System.out); - - int V = fr.nextInt(); // Number of vertices - int E = fr.nextInt(); // Number of edges - - Graph graph = new Graph(V); - - for (int i = 0; i < E; i++) { - int u = fr.nextInt(); - int v = fr.nextInt(); - graph.addEdge(u, v); - } - - int start = fr.nextInt(); // Starting node for BFS - - int[] distances = graph.bfs(start); - - // Output the shortest distance to all nodes - for (int i = 0; i < distances.length; i++) { - out.println("Shortest distance from node " + start + " to node " + i + " is " + distances[i]); - } - - out.close(); - } -} diff --git a/SimpleGraphTemplate.py b/SimpleGraphTemplate.py deleted file mode 100644 index e4cd309..0000000 --- a/SimpleGraphTemplate.py +++ /dev/null @@ -1,50 +0,0 @@ -from collections import deque, defaultdict - -class Graph: - def __init__(self, directed=False): - self.adj_list = defaultdict(list) - self.directed = directed - - def add_edge(self, u, v): - self.adj_list[u].append(v) - if not self.directed: - self.adj_list[v].append(u) - - def bfs(self, start): - # Dictionary to store distance from start node - distance = {node: float('inf') for node in self.adj_list} - distance[start] = 0 - - queue = deque([start]) - - while queue: - current_node = queue.popleft() - - for neighbor in self.adj_list[current_node]: - if distance[neighbor] == float('inf'): # Unvisited node - distance[neighbor] = distance[current_node] + 1 - queue.append(neighbor) - - return distance - - def print_graph(self): - for key, value in self.adj_list.items(): - print(f"{key}: {value}") - -# Example usage: -if __name__ == "__main__": - g = Graph(directed=False) - g.add_edge(1, 2) - g.add_edge(1, 3) - g.add_edge(2, 4) - g.add_edge(3, 5) - g.add_edge(4, 5) - - # Print the adjacency list (for debugging) - g.print_graph() - - # Perform BFS starting from node 1 - distances = g.bfs(1) - print("\nDistances from node 1:") - for node, dist in distances.items(): - print(f"Node {node}: Distance {dist}") diff --git a/Simplex.cpp b/Simplex.cpp deleted file mode 100644 index abdc643..0000000 --- a/Simplex.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// Two-phase simplex algorithm for solving linear programs of the form -// -// maximize c^T x -// subject to Ax <= b -// x >= 0 -// -// INPUT: A -- an m x n matrix -// b -- an m-dimensional vector -// c -- an n-dimensional vector -// x -- a vector where the optimal solution will be stored -// -// OUTPUT: value of the optimal solution (infinity if unbounded -// above, nan if infeasible) -// -// To use this code, create an LPSolver object with A, b, and c as -// arguments. Then, call Solve(x). - -#include -#include -#include -#include -#include - -using namespace std; - -typedef long double DOUBLE; -typedef vector VD; -typedef vector VVD; -typedef vector VI; - -const DOUBLE EPS = 1e-9; - -struct LPSolver { - int m, n; - VI B, N; - VVD D; - - LPSolver(const VVD &A, const VD &b, const VD &c) : - m(b.size()), n(c.size()), N(n + 1), B(m), D(m + 2, VD(n + 2)) { - for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) D[i][j] = A[i][j]; - for (int i = 0; i < m; i++) { B[i] = n + i; D[i][n] = -1; D[i][n + 1] = b[i]; } - for (int j = 0; j < n; j++) { N[j] = j; D[m][j] = -c[j]; } - N[n] = -1; D[m + 1][n] = 1; - } - - void Pivot(int r, int s) { - double inv = 1.0 / D[r][s]; - for (int i = 0; i < m + 2; i++) if (i != r) - for (int j = 0; j < n + 2; j++) if (j != s) - D[i][j] -= D[r][j] * D[i][s] * inv; - for (int j = 0; j < n + 2; j++) if (j != s) D[r][j] *= inv; - for (int i = 0; i < m + 2; i++) if (i != r) D[i][s] *= -inv; - D[r][s] = inv; - swap(B[r], N[s]); - } - - bool Simplex(int phase) { - int x = phase == 1 ? m + 1 : m; - while (true) { - int s = -1; - for (int j = 0; j <= n; j++) { - if (phase == 2 && N[j] == -1) continue; - if (s == -1 || D[x][j] < D[x][s] || D[x][j] == D[x][s] && N[j] < N[s]) s = j; - } - if (D[x][s] > -EPS) return true; - int r = -1; - for (int i = 0; i < m; i++) { - if (D[i][s] < EPS) continue; - if (r == -1 || D[i][n + 1] / D[i][s] < D[r][n + 1] / D[r][s] || - (D[i][n + 1] / D[i][s]) == (D[r][n + 1] / D[r][s]) && B[i] < B[r]) r = i; - } - if (r == -1) return false; - Pivot(r, s); - } - } - - DOUBLE Solve(VD &x) { - int r = 0; - for (int i = 1; i < m; i++) if (D[i][n + 1] < D[r][n + 1]) r = i; - if (D[r][n + 1] < -EPS) { - Pivot(r, n); - if (!Simplex(1) || D[m + 1][n + 1] < -EPS) return -numeric_limits::infinity(); - for (int i = 0; i < m; i++) if (B[i] == -1) { - int s = -1; - for (int j = 0; j <= n; j++) - if (s == -1 || D[i][j] < D[i][s] || D[i][j] == D[i][s] && N[j] < N[s]) s = j; - Pivot(i, s); - } - } - if (!Simplex(2)) return numeric_limits::infinity(); - x = VD(n); - for (int i = 0; i < m; i++) if (B[i] < n) x[B[i]] = D[i][n + 1]; - return D[m][n + 1]; - } -}; - -int main() { - - const int m = 4; - const int n = 3; - DOUBLE _A[m][n] = { - { 6, -1, 0 }, - { -1, -5, 0 }, - { 1, 5, 1 }, - { -1, -5, -1 } - }; - DOUBLE _b[m] = { 10, -4, 5, -5 }; - DOUBLE _c[n] = { 1, -1, 0 }; - - VVD A(m); - VD b(_b, _b + m); - VD c(_c, _c + n); - for (int i = 0; i < m; i++) A[i] = VD(_A[i], _A[i] + n); - - LPSolver solver(A, b, c); - VD x; - DOUBLE value = solver.Solve(x); - - cerr << "VALUE: " << value << endl; // VALUE: 1.29032 - cerr << "SOLUTION:"; // SOLUTION: 1.74194 0.451613 1 - for (size_t i = 0; i < x.size(); i++) cerr << " " << x[i]; - cerr << endl; - return 0; -} diff --git a/SplitString+stoi.cpp b/SplitString+stoi.cpp deleted file mode 100644 index 3e6cda6..0000000 --- a/SplitString+stoi.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include -using namespace std; -template -void split(const string &s, char delim, Out result) { - stringstream ss(s); - string item; - while (std::getline(ss, item, delim)) { - *(result++) = item; - } -} - -vector split(const string &s, char delim) { - vector elems; - split(s, delim, back_inserter(elems)); - return elems; -} -vector cur; -int main() { - cur=split("Hey|0|YO|5252",'|'); - for (auto x:cur) { - if (x[0]=='5') { - cout< g[100010]; Works on disconnected undirected graph too -#include -#define pb push_back -using namespace std; -int u,v,n,m,timez; -vector vis; -vector g[100010],low,d,cutpoints; -vector > bridges; -void dfs_cutpoints(int x,int par=-1) { - vis[x]=true; - low[x]=d[x]=timez++; - for (int i=0;i=d[x] && par!=-1) cutpoints.pb(x); - } - } - if (par==-1 && g[x].size()>1) cutpoints.pb(x); -} -void find_cutpoints() { - timez=0; - vis.assign(n,false),low.assign(n,-1),d.assign(n,-1); - for (int i=0;id[x]) bridges.pb(make_pair(x,g[x][i])); - } - } -} -void find_bridges() { - timez=0; - vis.assign(n,false),low.assign(n,-1),d.assign(n,-1); - for (int i=0;ibridges[i].second) swap(bridges[i].first,bridges[i].second); - sort(bridges.begin(),bridges.end()); -} -int main() {ios::sync_with_stdio(false);cin.tie(0); - cin>>n>>m; - for (int i=0;i>u>>v,g[u].pb(v),g[v].pb(u); - find_cutpoints(); find_bridges(); outputsort(); - cout<> (__builtin_ctz(v) + 1)); diff --git a/circle_tangent.cpp b/circle_tangent.cpp deleted file mode 100644 index 36091de..0000000 --- a/circle_tangent.cpp +++ /dev/null @@ -1,8 +0,0 @@ -//Returns a pair of the two points on the circle with radius r centered around c whos tangent lines intersect p. If p lies within the circle NaN-points are returned. P is intended to be Point. The first point is the one to the right as seen from the p towards c. -//usage : pair p = circleTangents(P(100,2),P(0,0),2); -template -pair circleTangents(const P &p, const P &c, double r) { - P a = p-c; - double x = r*r/a.dist2(), y = sqrt(x-x*x); - return make_pair(c+a*x+a.perp()*y, c+a*x-a.perp()*y); -} diff --git a/circum circle.cpp b/circum circle.cpp deleted file mode 100644 index 58231af..0000000 --- a/circum circle.cpp +++ /dev/null @@ -1,9 +0,0 @@ -//The circumcirle of a triangle is the circle intersecting all three vertices. ccRadius returns the radius of the circle going through points A, B and C and ccCenter returns the center of the same circle. -double ccRadius(const P& A, const P& B, const P& C) { - return (B-A).dist()*(C-B).dist()*(A-C).dist()/ - abs((B-A).cross(C-A))/2; -} -P ccCenter(const P& A, const P& B, const P& C) { - P b = C-A, c = B-A; - return A + (b*c.dist2()-c*b.dist2()).perp()/b.cross(c)/2; -} diff --git a/dates.cpp b/dates.cpp deleted file mode 100644 index 399e464..0000000 --- a/dates.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// Routines for performing computations on dates. In these routines, -// months are expressed as integers from 1 to 12, days are expressed -// as integers from 1 to 31, and years are expressed as 4-digit -// integers. - -#include -#include - -using namespace std; - -string dayOfWeek[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; - -// converts Gregorian date to integer (Julian day number) -int dateToInt (int m, int d, int y){ - return - 1461 * (y + 4800 + (m - 14) / 12) / 4 + - 367 * (m - 2 - (m - 14) / 12 * 12) / 12 - - 3 * ((y + 4900 + (m - 14) / 12) / 100) / 4 + - d - 32075; -} - -// converts integer (Julian day number) to Gregorian date: month/day/year -void intToDate (int jd, int &m, int &d, int &y){ - int x, n, i, j; - - x = jd + 68569; - n = 4 * x / 146097; - x -= (146097 * n + 3) / 4; - i = (4000 * (x + 1)) / 1461001; - x -= 1461 * i / 4 - 31; - j = 80 * x / 2447; - d = x - 2447 * j / 80; - x = j / 11; - m = j + 2 - 12 * x; - y = 100 * (n - 49) + i + x; -} - -// converts integer (Julian day number) to day of week -string intToDay (int jd){ - return dayOfWeek[jd % 7]; -} - -int main (int argc, char **argv){ - int jd = dateToInt (3, 24, 2004); - int m, d, y; - intToDate (jd, m, d, y); - string day = intToDay (jd); - - // expected output: - // 2453089 - // 3/24/2004 - // Wed - cout << jd << endl - << m << "/" << d << "/" << y << endl - << day << endl; -} diff --git a/dfsmatching.cpp b/dfsmatching.cpp deleted file mode 100644 index fafac1e..0000000 --- a/dfsmatching.cpp +++ /dev/null @@ -1,36 +0,0 @@ -* Description: This is a simple matching algorithm but should - * be just fine in most cases. Graph $g$ should be a list of - * neighbours of the left partition. $n$ is the size of the left - * partition and $m$ is the size of the right partition. - * If you want to get the matched pairs, $match[i]$ contains - * match for vertex $i$ on the right side or $-1$ if it's not - * matched. - * Time: O(EV) where $E$ is the number of edges and V is the number of vertices. - * Status: works - */ -#pragma once - -vi match; -vector seen; -bool find(int j, const vector& g) { - if (match[j] == -1) return 1; - seen[j] = 1; int di = match[j]; - trav(e, g[di]) - if (!seen[e] && find(e, g)) { - match[e] = di; - return 1; - } - return 0; -} -int dfs_matching(const vector& g, int n, int m) { - match.assign(m, -1); - rep(i,0,n) { - seen.assign(m, 0); - trav(j,g[i]) - if (find(j, g)) { - match[j] = i; - break; - } - } - return m - (int)count(all(match), -1); -} diff --git a/fraction class b/fraction class deleted file mode 100644 index b307d90..0000000 --- a/fraction class +++ /dev/null @@ -1,40 +0,0 @@ -struct NOS { - ll num,den; - NOS() {} - NOS(ll numn) : num(num) {den = 1;} - NOS(ll num,ll den) : num(num),den(den) { - ll G = __gcd(num, den); - num /= G; - den /= G; - } - NOS(const NOS &p) : num(p.num),den(p.den) {} - NOS operator + (const NOS &p) const { - ll num_=num*p.den+den*p.num,den_=den*p.den; - ll G=__gcd(num_,den_); - num_/=G; den_/=G; - return NOS(num_,den_); - } - NOS operator - (const NOS &p) const { - ll num_=num*p.den-den*p.num,den_=den*p.den; - ll G=__gcd(num_,den_); - num_/=G; den_/=G; - return NOS(num_,den_); - } - NOS operator * (const NOS &p) const { - ll a = num, b = den, c = p.num, d = p.den; - ll G1 = __gcd(a, d), G2 = __gcd(b, c); - a /= G1; d /= G1; - b /= G2; c /= G2; - a *= c; - b *= d; - ll G = __gcd(a, b); //extra - a /= G; b /= G; //extra - return NOS(a, b); - } - bool operator != (const NOS &p) const { - return (p.num != num or p.den != den); - } - bool operator == (const NOS &p) const { - return (p.num == num and p.den == den); - } -}; diff --git a/geometry.cpp b/geometry.cpp deleted file mode 100644 index acc3499..0000000 --- a/geometry.cpp +++ /dev/null @@ -1,231 +0,0 @@ -double INF = 1e100; -double EPS = 1e-12; -const double PI = 3.14159265358979323846264338327950288419716939937510L; -struct PT { - double x, y; - PT() {} - PT(double x, double y) : x(x), y(y) {} - PT(const PT &p) : x(p.x), y(p.y) {} - PT operator + (const PT &p) const { return PT(x+p.x, y+p.y); } - PT operator - (const PT &p) const { return PT(x-p.x, y-p.y); } - PT operator * (double c) const { return PT(x*c, y*c ); } - PT operator / (double c) const { return PT(x/c, y/c ); } - bool operator<(const PT &rhs) const { return make_pair(y,x) < make_pair(rhs.y,rhs.x); } - bool operator==(const PT &rhs) const { return make_pair(y,x) == make_pair(rhs.y,rhs.x); } -}; - -double dot(PT p, PT q) { return p.x*q.x+p.y*q.y; } -double dist2(PT p, PT q) { return dot(p-q,p-q); } -double cross(PT p, PT q) { return p.x*q.y-p.y*q.x; } -ostream &operator<<(ostream &os,const PT &p) {return os<<"("< -#define REMOVE_REDUNDANT -double area2(PT a, PT b, PT c) { return cross(a,b) + cross(b,c) + cross(c,a); } -#ifdef REMOVE_REDUNDANT -bool between(const PT &a, const PT &b, const PT &c) { - return (fabs(area2(a,b,c)) < EPS && (a.x-b.x)*(c.x-b.x) <= 0 && (a.y-b.y)*(c.y-b.y) <= 0);} -#endif -void ConvexHull(vector &pts) { - sort(pts.begin(), pts.end()); - pts.erase(unique(pts.begin(), pts.end()), pts.end()); - vector up, dn; - for (int i = 0; i < pts.size(); i++) { - while (up.size() > 1 && area2(up[up.size()-2], up.back(), pts[i]) >= 0) up.pop_back(); - while (dn.size() > 1 && area2(dn[dn.size()-2], dn.back(), pts[i]) <= 0) dn.pop_back(); - up.push_back(pts[i]); - dn.push_back(pts[i]); - } - pts = dn; - for (int i = (int) up.size() - 2; i >= 1; i--) pts.push_back(up[i]); -#ifdef REMOVE_REDUNDANT - if (pts.size() <= 2) return; - dn.clear(); - dn.push_back(pts[0]); - dn.push_back(pts[1]); - for (int i = 2; i < pts.size(); i++) { - if (between(dn[dn.size()-2], dn[dn.size()-1], pts[i])) dn.pop_back(); - dn.push_back(pts[i]); - } - if (dn.size() >= 3 && between(dn.back(), dn[0], dn[1])) { - dn[0] = dn.back(); - dn.pop_back(); - } - pts = dn; -#endif -} // - -// project point c onto line through a and b -// assuming a != b -PT ProjectPointLine(PT a, PT b, PT c) {return a + (b-a)*dot(c-a, b-a)/dot(b-a, b-a);} - -// project point c onto line segment through a and b -PT ProjectPointSegment(PT a, PT b, PT c) { - double r = dot(b-a,b-a); - if (fabs(r) < EPS) return a; - r = dot(c-a, b-a)/r; - if (r < 0) return a; - if (r > 1) return b; - return a + (b-a)*r; -} - -// reflection of point p on line ab -PT PointReflectByLine(PT a,PT b,PT p) { - PT ret=ProjectPointLine(a,b,p); - return (ret+ret-p); -} - -// compute distance from c to segment between a and b -double DistancePointSegment(PT a,PT b,PT c){return sqrt(dist2(c,ProjectPointSegment(a,b,c)));} -// compute distance between point (x,y,z) and plane ax+by+cz=d -double DistancePointPlane(double x, double y, double z, - double a, double b, double c, double d) { - return fabs(a*x+b*y+c*z-d)/sqrt(a*a+b*b+c*c); -} - -// determine if lines from a to b and c to d are parallel or collinear -bool LinesParallel(PT a, PT b, PT c, PT d) { return fabs(cross(b-a, c-d)) < EPS; } - -bool LinesCollinear(PT a, PT b, PT c, PT d) { - return LinesParallel(a, b, c, d) - && fabs(cross(a-b, a-c)) < EPS - && fabs(cross(c-d, c-a)) < EPS; -} - -// determine if line segment from a to b intersects with -// line segment from c to d -bool SegmentsIntersect(PT a, PT b, PT c, PT d) { - if (LinesCollinear(a, b, c, d)) { - if (dist2(a, c) < EPS || dist2(a, d) < EPS || - dist2(b, c) < EPS || dist2(b, d) < EPS) return true; - if (dot(c-a, c-b) > 0 && dot(d-a, d-b) > 0 && dot(c-b, d-b) > 0) - return false; - return true; - } - if (cross(d-a, b-a) * cross(c-a, b-a) > 0) return false; - if (cross(a-c, d-c) * cross(b-c, d-c) > 0) return false; - return true; -} - -// compute intersection of line passing through a and b -// with line passing through c and d, assuming that unique -// intersection exists; for segment intersection, check if -// segments intersect first -PT ComputeLineIntersection(PT a, PT b, PT c, PT d) { - b=b-a; d=c-d; c=c-a; - assert(dot(b, b) > EPS && dot(d, d) > EPS); - return a + b*cross(c, d)/cross(b, d); -} - -// compute center of circle given three points -PT ComputeCircleCenter(PT a, PT b, PT c) { - b=(a+b)/2; - c=(a+c)/2; - return ComputeLineIntersection(b, b+RotateCW90(a-b), c, c+RotateCW90(a-c)); -} - -// determine if point is in a possibly non-convex polygon (by William -// Randolph Franklin); returns 1 for strictly interior points, 0 for -// strictly exterior points, and 0 or 1 for the remaining points. -// Note that it is possible to convert this into an *exact* test using -// integer arithmetic by taking care of the division appropriately -// (making sure to deal with signs properly) and then by writing exact -// tests for checking point on polygon boundary -bool PointInPolygon(const vector &p, PT q) { - bool c = 0; - for (int i = 0; i < p.size(); i++){ - int j = (i+1)%p.size(); - if ((p[i].y <= q.y && q.y < p[j].y || - p[j].y <= q.y && q.y < p[i].y) && - q.x < p[i].x + (p[j].x - p[i].x) * (q.y - p[i].y) / (p[j].y - p[i].y)) - c = !c; - } - return c; -} - -// determine if point is on the boundary of a polygon -bool PointOnPolygon(const vector &p, PT q) { - for (int i = 0; i < p.size(); i++) - if (dist2(ProjectPointSegment(p[i], p[(i+1)%p.size()], q), q) < EPS) return true; - return false; -} - -// is point a on segment bc -bool PointOnSegment(PT a,PT b,PT c) { - if (!LinesParallel(a,b,a,c)) return false; - if (b.x<=a.x && a.x<=c.x) return true; - if (c.x<=a.x && a.x<=b.x) return true; - return false; -} - -// compute intersection of line through points a and b with -// circle centered at c with radius r > 0 -vector CircleLineIntersection(PT a, PT b, PT c, double r) { - vector ret; - b = b-a; - a = a-c; - double A = dot(b, b); - double B = dot(a, b); - double C = dot(a, a) - r*r; - double D = B*B - A*C; - if (D < -EPS) return ret; - ret.push_back(c+a+b*(-B+sqrt(D+EPS))/A); - if (D > EPS) - ret.push_back(c+a+b*(-B-sqrt(D))/A); - return ret; -} -// compute intersection of circle centered at a with radius r -// with circle centered at b with radius R -vector CircleCircleIntersection(PT a, PT b, double r, double R) { - vector ret; - double d = sqrt(dist2(a, b)); - if (d > r+R || d+min(r, R) < max(r, R)) return ret; - double x = (d*d-R*R+r*r)/(2*d); - double y = sqrt(r*r-x*x); - PT v = (b-a)/d; - ret.push_back(a+v*x + RotateCCW90(v)*y); - if (y > 0) ret.push_back(a+v*x - RotateCCW90(v)*y); - return ret; -} - -// This code computes the area or centroid of a (possibly nonconvex) -// polygon, assuming that the coordinates are listed in a clockwise or -// counterclockwise fashion. Note that the centroid is often known as -// the "center of gravity" or "center of mass". -double ComputeSignedArea(const vector &p) { - double area = 0; - for(int i = 0; i < p.size(); i++) { - int j = (i+1) % p.size(); - area += p[i].x*p[j].y - p[j].x*p[i].y; - } - return area / 2.0; -} - -double ComputeArea(const vector &p) {return fabs(ComputeSignedArea(p));} - -PT ComputeCentroid(const vector &p) { - PT c(0,0); - double scale = 6.0 * ComputeSignedArea(p); - for (int i = 0; i < p.size(); i++){ - int j = (i+1) % p.size(); - c = c + (p[i]+p[j])*(p[i].x*p[j].y - p[j].x*p[i].y); - } - return c / scale; -} -// tests whether or not a given polygon (in CW or CCW order) is simple -bool IsSimple(const vector &p) { - for (int i = 0; i < p.size(); i++) { - for (int k = i+1; k < p.size(); k++) { - int j = (i+1) % p.size(); - int l = (k+1) % p.size(); - if (i == l || j == k) continue; - if (SegmentsIntersect(p[i], p[j], p[k], p[l])) - return false; - } - } - return true; -} diff --git a/manacher.cpp b/manacher.cpp deleted file mode 100644 index f6b1db8..0000000 --- a/manacher.cpp +++ /dev/null @@ -1,14 +0,0 @@ -Description: For each position in a string, computes p[0][i] = half length of - * longest even palindrome around pos i, p[1][i] = longest odd (half rounded down). - * Time: O(N) */ -void manacher(const string& s) { - int n = sz(s); - vi p[2] = {vi(n+1), vi(n)}; - rep(z,0,2) for (int i=0,l=0,r=0; i < n; i++) { - int t = r-i+!z; - if (i=1 && R+1r) l=L, r=R; -}} diff --git a/nCr with mod precompute.cpp b/nCr with mod precompute.cpp deleted file mode 100644 index d8be5f8..0000000 --- a/nCr with mod precompute.cpp +++ /dev/null @@ -1,12 +0,0 @@ -long long fact[N], ifact[N], inv[N]; -void _pre() { - fact[1] = fact[0] = 1; ifact[0] = ifact[1] = 1; inv[0] = inv[1] = 1; - for (int i = 1; i < N; ++i) fact[i] = (fact[i - 1] * i) % mod; - for (int i = 2; i < N; ++i) inv[i] = (((-(mod / i) * inv[mod % i]) % mod) + mod) % mod; - for (int i = 2; i < N; ++i) ifact[i] = (ifact[i - 1] * inv[i]) % mod; -} -long long C(int n, int k) { - if (k > n) return 0; - if (n < 0 || k < 0) return 0; - return (fact[n] * ((ifact[n - k] * ifact[k]) % mod)) % mod; -} diff --git a/phi.cpp b/phi.cpp deleted file mode 100644 index 702c598..0000000 --- a/phi.cpp +++ /dev/null @@ -1,17 +0,0 @@ -const int LIM = 5000000; int phi[LIM]; -void calculatePhi() { - rep(i,0,LIM) phi[i] = i&1 ? i : i/2; - for(int i = 3; i < LIM; i += 2) if(phi[i] == i) - for(int j = i; j < LIM; j += i) phi[j] -= phi[j] / i; -} -//Mobius Inversion : Let required be {sum_of_g=1-to-Gmax}h(g)*cnt[g] -//Then h(g)={sum_of_d:d|g}f(d) //f(n)={sum_of_d:d|n}f(d)*mobius(n/d) -FOR(i,1,n) for (int j=1;j<=n;j+=i) f[j] += h[i] * ยต[j/i]; -void preprocess() { // Compute mobius fucntion mu[] - FOR(i,1,111100) mu[i]=primechk[i]=1;primechk[1]=0; - FOR(i,2,111100) { - if(primechk[i]==0) continue; - mu[i]=-mu[i]; - for (int j=2;i*j<=111100;j++) primechk[i*j]=0,mu[i*j]=(j%i==0?0:mu[i*j]=-mu[i*j]; - } -} diff --git a/point in poly log N.cpp b/point in poly log N.cpp deleted file mode 100644 index ce37ba7..0000000 --- a/point in poly log N.cpp +++ /dev/null @@ -1,23 +0,0 @@ -struct point {lint x,y;} pa[M],pb[M]; -lint na,nb; -lint isleft(point A,point B,point C) { - return (ll(B.x-A.x)*ll(C.y-A.y)-ll(C.x-A.x)*ll(B.y-A.y)); -} -bool pt_in_poly(point p) { - int a=1,b=na-1,c; - if (isleft(pa[0],pa[a],pa[b])<=0) swap(a,b); - if (isleft(pa[0],pa[a],p)<=0 || isleft(pa[0],pa[b],p)>=0) return false; - while (abs(a-b)>1) { - c=(a+b)/2; - if (isleft(pa[0],pa[c],p)<=0) b=c; else a=c; - } - return (isleft(pa[a],pa[b],p)>0); -} -int main() { - cin>>na; - for (int i=0;i>pa[i].x>>pa[i].y; - cin>>nb; - for (int i=0;i>pb[i].x>>pb[i].y; - for (int i=0;i -#include - -int main() -{ - std::random_device rd; //Will be used to obtain a seed for the random number engine - std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd() - - //Various range distributions - std::uniform_int_distribution<> dis(1, 6); - std::uniform_real_distribution<> dis(1.0, 2.0); - - std::geometric_distribution<> d; // same as std::negative_binomial_distribution<> d(1, 0.5); - - // if particles decay once per second on average, - // how much time, in seconds, until the next one? - std::exponential_distribution<> d(1); //This is the continuous counterpart of geometric_distribution - - // values near the mean are the most likely - // standard deviation affects the dispersion of generated values from the mean - std::normal_distribution<> d{5,2}; //5 is mean, dispersion from mean is at range +/-2 - - - for (int n=0; n<10; ++n) - //Use dis to transform the random unsigned int generated by gen into an int in [1, 6] - std::cout << dis(gen) << ' '; - std::cout << '\n'; -} - -/* -int main() -{ - std::random_device rd; - std::mt19937 gen(rd()); - // perform 4 trials, each succeeds 1 in 2 times - std::binomial_distribution<> d(4, 0.5); - - std::map hist; - for (int n = 0; n < 10000; ++n) { - ++hist[d(gen)]; - } - for (auto p : hist) { - std::cout << p.first << ' ' - << std::string(p.second/100, '*') << '\n'; - } -} -*/ diff --git a/spherical distance.cpp b/spherical distance.cpp deleted file mode 100644 index 9151667..0000000 --- a/spherical distance.cpp +++ /dev/null @@ -1,8 +0,0 @@ -double sphericalDistance(double f1, double t1, - double f2, double t2, double radius) { - double dx = sin(t2)*cos(f2) - sin(t1)*cos(f1); - double dy = sin(t2)*sin(f2) - sin(t1)*sin(f1); - double dz = cos(t2) - cos(t1); - double d = sqrt(dx*dx + dy*dy + dz*dz); - return radius*2*asin(d/2); -} diff --git a/ternary search.cpp b/ternary search.cpp deleted file mode 100644 index e8fe4d8..0000000 --- a/ternary search.cpp +++ /dev/null @@ -1,22 +0,0 @@ - /*Find the smallest i in $[a,b]$ that maximizes $f(i)$, assuming that $f(a) < \dots < f(i) \ge \dots \ge f(b)$. - * To reverse which of the sides allows non-strict inequalities, change the < marked with (A) to <=, and reverse the loop at (B). - * To minimize $f$, change it to >, also at (B). - * Status: tested - * Usage: - int ind = ternSearch(0,n-1,[\&](int i){return a[i];}); - * Time: O(\log(b-a)) - */ - -template -int ternSearch(int a, int b, F f) { - assert(a <= b); - while (b - a >= 5) { - int mid = (a + b) / 2; - if (f(mid) < f(mid+1)) // (A) - a = mid; - else - b = mid+1; - } - rep(i,a+1,b+1) if (f(a) < f(i)) a = i; // (B) - return a; -} diff --git a/treap.cpp b/treap.cpp deleted file mode 100644 index fff7163..0000000 --- a/treap.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include -using namespace std; -#define ll long long -typedef struct node { - struct node *l,*r; - ll size,lazy,sum,val,prior; -}node; - -typedef node* pnode; -pnode head; - -ll sz(pnode t) { - return t?t->size:0; -} - -void upd_sz(pnode t) { - if(t) t->size = sz(t->l)+1+sz(t->r); -} - -void lazy(pnode t) { - if(!t || !t->lazy) return; - t->val += t->lazy; - t->sum += t->lazy*sz(t); - if(t->l) t->l->lazy += t->lazy; - if(t->r) t->r->lazy += t->lazy; - t->lazy = 0; -} - -void reset(pnode t) { - if(!t) return; - t->sum = t->val; -} - -void combine(pnode &t,pnode l,pnode r) { - if(!l || !r) return void (t=l?l:r); - t->sum = l->sum+r->sum; -} - -void operation(pnode t) { - if(!t) return; - reset(t); - lazy(t->l);lazy(t->r); - combine(t,t->l,t); - combine(t,t,t->r); -} - -void split(pnode t,pnode &l,pnode &r,ll pos,ll add=0) { - if(!t) return void(l = r = NULL); - ll cur_pos = add + sz(t->l); - lazy(t); - if(cur_pos <= pos) split(t->r,t->r,r,pos,cur_pos+1),l=t; - else split(t->l,l,t->l,pos,add),r=t; - upd_sz(t); - operation(t); -} -void merge(pnode &t,pnode l,pnode r) { - lazy(l);lazy(r); - if(!l || !r) t=l?l:r; - else if(l->prior > r->prior) merge(l->r,l->r,r),t=l; - else merge(r->l,l,r->l),t=r; - upd_sz(t); - operation(t); -} - -void init(pnode t,ll val) { - t->l = t->r = NULL; - t->val = t->sum = val; - t->size = 1,t->lazy=0; - t->prior = rand(); -} - -void range_update(pnode t,ll l,ll r,ll val) { - pnode L,mid,R; - split(t,L,mid,l-1); - split(mid,t,R,r-l); - t->lazy += val; - merge(mid,L,t); - merge(t,mid,R); -} - -ll range_query(pnode t,ll l,ll r) { - pnode L,mid,R; - split(t,L,mid,l-1); - split(mid,t,R,r-l); - ll ans=t->sum; - merge(mid,L,t); - merge(t,mid,R); - return ans; -} - -int main() { - ll t; - cin>>t; - while(t--) { - ll i,j,k,l,n,m; - cin>>n>>m; - for(i=0;i>j>>k>>l; - if(j) - cout<>j; - range_update(head,k-1,l-1,j); - } - } - } - return 0; -} diff --git a/unordered_map for pair as key b/unordered_map for pair as key deleted file mode 100644 index f465260..0000000 --- a/unordered_map for pair as key +++ /dev/null @@ -1,19 +0,0 @@ -struct hash_pair { - template - size_t operator()(const pair& p) const - { - auto hash1 = hash{}(p.first); - auto hash2 = hash{}(p.second); - - if (hash1 != hash2) { - return hash1 ^ hash2; - } - - // If hash1 == hash2, their XOR is zero. - return hash1; - } -}; - -int main() { - unordered_map, int, hash_pair> yo; -}