Template

VC 的一些模板:

网络流(待补全)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
namespace Flow {
	namespace max_flow {
		using flow_type = int;
		constexpr int inf = 1 << 30;
		int St, Ed;
		struct edge {
			int to;
			flow_type c;
			int pos;
			edge(int To = 0, flow_type C = 0, int Pos = 0): to(To), c(C), pos(Pos) {}
		};
		vector<edge> g[10005];
		void add_edge(int from, int to, flow_type c, bool directed = true) {
			// cerr << "from " << from << " to " << to << " with " << c << '\n';
			if(!c) return;
			g[from].push_back(edge(to, c));
			g[to].push_back(edge(from, directed ? 0 : c));
			g[from].back().pos = g[to].size() - 1;
			g[to].back().pos = g[from].size() - 1;
		}
		namespace Dinic {
			int dep[10005], cur[10005];
			queue<int> q;
			bool bfs(int s, int t) {
				fill(dep + St, dep + 1 + Ed, 0);
				dep[s] = 1;
				q.push(s);
				int now;
				while(!q.empty()) {
					now = q.front();
					q.pop();
					for(const auto& i : g[now]) {
						if(!dep[i.to] && i.c) {
							dep[i.to] = dep[now] + 1;
							q.push(i.to);
						}
					}
				}
				return dep[t];
			}
			flow_type dfs(int now, flow_type flw, const int& t) {
				if(now == t) return flw;
				flow_type rest = flw, f;
				const int len = (int)g[now].size();
				while(cur[now] < len) {
					auto& i = g[now][cur[now]];
					if(dep[i.to] == dep[now] + 1 && i.c) {
						f = dfs(i.to, min(i.c, rest), t);
						if(!f) dep[i.to] = 0;
						i.c -= f;
						g[i.to][i.pos].c += f;
						rest -= f;
						if(!rest) break;
					}
					++cur[now];
				}
				return flw - rest;
			}
			flow_type Dinic(int s, int t) {
				flow_type flow = 0;
				while(bfs(s, t)) {
					fill(cur + St, cur + 1 + Ed, 0);
					flow += dfs(s, inf, t);
				}
				return flow;
			}
		}
		namespace HLPP {
			int level, S, T, ht[10005], gap[20005];
			flow_type ex[10005];
			stack<int> b[20005];
			queue<int> q;
			bool bfs(int s, int t) {
				while(!q.empty()) q.pop();
				fill(ht + St, ht + 1 + Ed, inf);
				ht[t] = 0;
				q.push(t);
				int now;
				while(!q.empty()) {
					now = q.front();
					q.pop();
					for(const auto& i : g[now]) {
						if(g[i.to][i.pos].c && ht[i.to] > ht[now] + 1) {
							ht[i.to] = ht[now] + 1;
							q.push(i.to);
						}
					}
				}
				return ht[s] != inf;
			}
			bool push(int now, bool init = false) {
				flow_type f;
				for(auto& i : g[now]) {
					if(i.c > 0 && (init || ht[now] == ht[i.to] + 1) && ht[i.to] != inf) {
						f = init ? i.c : min(i.c, ex[now]);
						if(i.to != S && i.to != T && !ex[i.to]) {
							b[ht[i.to]].push(i.to);
							level = max(level, ht[i.to]);
						}
						ex[now] -= f, ex[i.to] += f;
						i.c -= f, g[i.to][i.pos].c += f;
						if(!ex[now]) return false;
					}
				}
				return true;
			}
			void relabel(int now) {
				ht[now] = inf;
				for(const auto& i : g[now]) {
					if(i.c) ht[now] = min(ht[now], ht[i.to]);
				}
				++ht[now];
				b[ht[now]].push(now);
				level = max(level, ht[now]);
				++gap[ht[now]];
			}
			int select() {
				while(b[level].empty() && (~level)) --level;
				if(!(~level)) return 0;
				int ret = b[level].top();
				b[level].pop();
				return ret;
			}
			flow_type HLPP(int s, int t) {
				S = s, T = t;
				if(!bfs(s, t)) return 0;
				int n = Ed - St + 1;
				ht[s] = n, level = 0;
				fill(gap + St, gap + 1 + Ed, 0);
				fill(ex + St, ex + 1 + Ed, 0);
				for(int i = 0; i <= (n << 1); ++i) {
					while(!b[i].empty()) b[i].pop();
				}
				for(int i = St; i <= Ed; ++i) {
					if(ht[i] != inf) {
						++gap[ht[i]];
					}
				}
				push(s, true);
				int now;
				while((now = select())) {
					if(push(now)) {
						if(!(--gap[ht[now]])) {
							for(int i = St; i <= Ed; ++i) {
								if(i != s && ht[i] > ht[now] && ht[i] != inf) ht[i] = max(ht[i], n + 1);
							}
						}
						relabel(now);
					}
				}
				return ex[t];
			}
		}
	}
	namespace cost_flow {
		constexpr int inf = 1 << 30;
		using flow_type = int;
		using cost_type = int;
		int St, Ed;
		flow_type flow;
		cost_type cost;
		struct edge {
			int to;
			flow_type c;
			cost_type cost;
			int pos;
			edge(int To = 0, flow_type C = 0, cost_type Cost = 0, int Pos = 0): to(To), c(C), cost(Cost), pos(Pos) {}
		};
		vector<edge> g[10005];
		bool vis[10005];
		void add_edge(int from, int to, flow_type c, cost_type cost) {
			// cerr << "from " << from << " to " << to << " with " << c << " cost " << cost << '\n';
			g[from].push_back(edge(to, c, cost));
			g[to].push_back(edge(from, 0, -cost));
			g[from].back().pos = g[to].size() - 1;
			g[to].back().pos = g[from].size() - 1;
		}
		namespace Dinic {
			int cur[10005];
			cost_type dis[10005];
			queue<int> q;
			bool spfa(int s, int t) {
				fill(dis + St, dis + 1 + Ed, inf);
				dis[s] = 0;
				q.push(s);
				int now;
				while(!q.empty()) {
					now = q.front();
					q.pop();
					vis[now] = false;
					for(const auto& i : g[now]) {
						if(dis[i.to] > dis[now] + i.cost && i.c) {
							dis[i.to] = dis[now] + i.cost;
							if(!vis[i.to]) {
								vis[i.to] = true;
								q.push(i.to);
							}
						}
					}
				}
				return dis[t] < inf;
			}
			flow_type dfs(int now, flow_type flw, const int& t) {
				if(now == t) return flw;
				vis[now] = true;
				flow_type rest = flw, f;
				const int len = (int)g[now].size();
				while(cur[now] < len) {
					auto& i = g[now][cur[now]];
					if(!vis[i.to] && dis[i.to] == dis[now] + i.cost && i.c) {
						f = dfs(i.to, min(i.c, rest), t);
						if(!f) dis[i.to] = inf;
						i.c -= f;
						g[i.to][i.pos].c += f;
						rest -= f;
						cost += f * i.cost;
						if(!rest) break;
					}
					++cur[now];
				}
				vis[now] = false;
				return flw - rest;
			}
			void Dinic(int s, int t) {
				flow = cost = 0;
				while(spfa(s, t)) {
					fill(cur + St, cur + 1 + Ed, 0);
					flow += dfs(s, inf, t);
				}
			}
		}
	}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	return 0;
}

计算几何(待补全)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
namespace geometry {
	const double pi = acos(-1.0), eps = 1e-6;
	bool Equal(double e1, double e2) {return abs(e1 - e2) < eps;}
	class pnt {
	public:
		double x, y;
		pnt(double X = 0.0, double Y = 0.0): x(X), y(Y) {}
		pnt operator = (const pnt& _) {x = _.x, y = _.y; return *this;}
		bool operator == (const pnt& _) const {return sqrt((x - _.x) * (x - _.x) + (y - _.y) * (y - _.y)) < eps;}
	};
	class vct {
	public:
		double x, y, rho, phi;
		vct(double X = 0.0, double Y = 0.0): x(X), y(Y) {update();}
		vct(double X_1, double Y_1, double X_2, double Y_2): x(X_2 - X_1), y(Y_2 - Y_1) {update();}
		vct(pnt p1, pnt p2): x(p2.x - p1.x), y(p2.y - p1.y) {update();}
		vct operator = (const vct& _) {x = _.x, y = _.y; update(); return *this;}
		vct operator + (const vct& _) const {return vct(x + _.x, y + _.y);}
		vct operator - (const vct& _) const {return vct(x - _.x, y - _.y);}
		vct operator - () const {return vct(-x, -y);}
		vct operator * (const double& _) const {return vct(x * _, y * _);}
		vct operator += (const vct& _) {*this = *this + _; update(); return *this;}
		vct operator -= (const vct& _) {*this = *this - _; update(); return *this;}
		vct operator *= (const double& _) {*this = *this * _; update(); return *this;}
		double operator * (const vct& _) const {return x * _.x + y * _.y;}
		double operator ^ (const vct& _) const {return x * _.y - y * _.x;}
		friend vct operator * (const double& _, const vct& x) {return x * _;}
		void update(bool flag = false) {
			if(flag) x = rho * cos(phi), y = rho * sin(phi);
			else rho = sqrt(x * x + y * y), phi = atan2(y, x);
		}
	};
	class cir {
	public:
		pnt ctr;
		double r;
		cir(double x = 0.0, double y = 0.0, double R = 0.0): ctr(x, y), r(R) {}
		cir operator = (const cir& _) {ctr = _.ctr; r = _.r; return *this;}
	};
	class sgt {
	public:
		pnt ps, pt;
		vct v;
		sgt(double x_1 = 0.0, double y_1 = 0.0, double x_2 = 0.0, double y_2 = 0.0): ps(x_1, y_1), pt(x_2, y_2), v(x_2 - x_1, y_2 - y_1) {}
		sgt operator = (const sgt& _) {ps = _.ps, pt = _.pt, v = _.v; return *this;}
	};
	double dis(const pnt& p1, const pnt& p2) {return vct(p1.x - p2.x, p1.y - p2.y).rho;}
	bool collinear(sgt s1, sgt s2) {
		if(Equal(s1.ps.x, s1.pt.x) || Equal(s2.ps.x, s2.pt.x)) {
			return Equal(s1.ps.x, s1.pt.x) && Equal(s2.ps.x, s2.pt.x) && Equal(s1.ps.x, s2.ps.x);
		}
		double k1 = (s1.pt.y - s1.ps.y) / (s1.pt.x - s1.ps.x), k2 = (s2.pt.y - s2.ps.y) / (s2.pt.x - s2.ps.x);
		double b1 = s1.ps.y - s1.ps.x * k1, b2 = s2.ps.y - s2.ps.x * k2;
		return Equal(k1, k2) && Equal(b1, b2);
	}
	bool repel_check(sgt s1, sgt s2) {
		double x1_1 = min(s1.ps.x, s1.pt.x), x2_1 = max(s1.ps.x, s1.pt.x);
		double y1_1 = min(s1.ps.y, s1.pt.y), y2_1 = max(s1.ps.y, s1.pt.y);
		double x1_2 = min(s2.ps.x, s2.pt.x), x2_2 = max(s2.ps.x, s2.pt.x);
		double y1_2 = min(s2.ps.y, s2.pt.y), y2_2 = max(s2.ps.y, s2.pt.y);
		double x_1 = max(x1_1, x1_2), x_2 = min(x2_1, x2_2);
		double y_1 = max(y1_1, y1_2), y_2 = min(y2_1, y2_2);
		return !(x_1 <= x_2 + eps && y_1 <= y_2 + eps);
	}
	bool stand_check(sgt s1, sgt s2) {
		double s1s = s1.v ^ vct(s1.ps, s2.ps), s1t = s1.v ^ vct(s1.ps, s2.pt);
		double s2s = s2.v ^ vct(s2.ps, s1.ps), s2t = s2.v ^ vct(s2.ps, s1.pt);
		return s1s * s1t <= 0.0 && s2s * s2t <= 0.0;
	}
	bool intsct(sgt s1, sgt s2) {
		return !repel_check(s1, s2) && stand_check(s1, s2);
		// double s = s1.v ^ s2.v;
		// return abs(s) > eps;
	}
	pnt intsct_pnt(sgt s1, sgt s2) {
		if(!intsct(s1, s2)) return pnt(INFINITY, INFINITY);
		if(Equal(s1.ps.x, s1.pt.x)) {
			double k = (s2.pt.y - s2.ps.y) / (s2.pt.x - s2.ps.x);
			return pnt(s1.ps.x, s2.ps.y + (s1.pt.x - s2.ps.x) * k);
		}
		if(Equal(s2.ps.x, s2.pt.x)) {
			double k = (s1.pt.y - s1.ps.y) / (s1.pt.x - s1.ps.x);
			return pnt(s2.ps.x, s1.ps.y + (s2.pt.x - s1.ps.x) * k);
		}
		double k1 = (s1.pt.y - s1.ps.y) / (s1.pt.x - s1.ps.x), k2 = (s2.pt.y - s2.ps.y) / (s2.pt.x - s2.ps.x);
		double b1 = s1.ps.y - s1.ps.x * k1, b2 = s2.ps.y - s2.ps.x * k2;
		double x = (b2 - b1) / (k1 - k2);
		double y = k1 * x + b1;
		return pnt(x, y);
	}
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	return 0;
}

modint

constexpr int mod = 998244353;
struct modint; modint ksm(modint x, ll y);
struct modint {
	int x;
	modint(int v = 0): x(v) {}
	friend modint operator + (const modint& x, const modint& y) {return x.x + y.x >= mod ? x.x + y.x - mod : x.x + y.x;}
	friend modint operator - (const modint& x, const modint& y) {return x.x < y.x ? x.x - y.x + mod : x.x - y.x;}
	friend modint operator * (const modint& x, const modint& y) {return (ll)x.x * y.x % mod;}
	friend modint operator / (const modint& x, const modint& y) {return x * ksm(y, mod - 2);}
	friend modint operator - (const modint& x) {return mod - x.x;}
	modint operator ++ (int) {auto ret(x); if((++x) == mod) x = 0; return ret;}
	modint& operator ++ () {if((++x) == mod) x = 0; return *this;}
	modint operator -- (int) {auto ret(x); if(!(x--)) x = mod - 1; return ret;}
	modint& operator -- () {if(!(x--)) x = mod - 1; return *this;}
	modint operator = (const modint& _) {x = _.x; return *this;}
	modint operator += (const modint& _) {*this = *this + _; return *this;}
	modint operator -= (const modint& _) {*this = *this - _; return *this;}
	modint operator *= (const modint& _) {*this = *this * _; return *this;}
	modint operator /= (const modint& _) {*this = *this / _; return *this;}
	bool operator == (const modint& _) const {return x == _.x;}
	bool operator != (const modint& _) const {return x != _.x;}
	friend istream& operator >> (istream& in, modint& _) {static ll tmp; in >> tmp; _ = tmp; return in;}
	friend ostream& operator << (ostream& out, const modint& _) {return out << _.x;}
};
modint ksm(modint x, ll y) {
	modint ret = 1;
	while(y) {if(y & 1) ret *= x; x *= x, y >>= 1;}
	return ret;
}
posted @ 2024-01-08 21:09  A_box_of_yogurt  阅读(4)  评论(0编辑  收藏  举报  来源
Document