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;
}
本文来自博客园,作者:A_box_of_yogurt,转载请注明原文链接:https://www.cnblogs.com/A-box-of-yogurt/p/18016387