老莽の模板库

代码头
#include<bits/stdc++.h>

using namespace std;

#define Reimu inline void // 灵梦赛高
#define Marisa inline int // 魔理沙赛高
#define Sanae inline bool // 早苗赛高
#define Reisen inline LL  // 铃仙赛高

typedef long long LL;
typedef unsigned long long ULL;
typedef __int128 Suika;

inline ostream &operator<<(ostream &cout, Suika x) {
	static const LL LIM = 1e18;
	if (x < 0) cout << '-', x = -x;
	return x < LIM ? cout << LL(x) : cout << LL(x / LIM) << setw(18) << setfill('0') << LL(x % LIM);
}

typedef pair<int, int> Pii;
typedef tuple<int, int, int> Tiii;
#define fi first
#define se second

#define ALL(vec) vec.begin(), vec.end()
#define TY(type) const type&

#define BT(func) __builtin_##func
#define BTL(func) __builtin_##func##ll

template<typename Ty>
Reimu clear(Ty &x) { Ty().swap(x); }

template<typename Ty>
Reimu clear(Ty &x) { Ty().swap(x); }
template<typename Ty>
Reimu max_(Ty &x, TY(Ty) y) { if (y > x) x = y; }
template<typename Ty>
Reimu min_(Ty &x, TY(Ty) y) { if (y < x) x = y; }

int main() {
	ios::sync_with_stdio(false); cin.tie(nullptr);
	
	return 0;
}
取模类
struct ModInt {
	static const unsigned P = 998244353;
	static inline unsigned reduce(unsigned x) { return x < P ? x : x - P; }

	unsigned x;
	ModInt(unsigned x = 0): x(x) {}

	friend ModInt operator-(ModInt x) { return reduce(P - x.x); }
	friend ModInt operator+(ModInt x, ModInt y) { return reduce(x.x + y.x); }
	friend ModInt operator-(ModInt x, ModInt y) { return reduce(P + x.x - y.x); }
	friend ModInt operator*(ModInt x, ModInt y) { return 1ULL * x.x * y.x % P; }
	friend ModInt &operator+=(ModInt &x, ModInt y) { return x = x + y; }
	friend ModInt &operator-=(ModInt &x, ModInt y) { return x = x - y; }
	friend ModInt &operator*=(ModInt &x, ModInt y) { return x = x * y; }

	friend ModInt qpow(ModInt x, int y) { ModInt res = 1; for (; y; y >>= 1, x *= x) if (y & 1) res *= x; return res; }

	friend ModInt operator~(ModInt x) { return qpow(x, P - 2); }
	friend ModInt operator/(ModInt x, ModInt y) { return x * ~y; }
	friend ModInt &operator/=(ModInt &x, ModInt y) { return x *= ~y; }

	friend istream &operator>>(istream &cin, ModInt &x) { return cin >> x.x; }
	friend ostream &operator<<(ostream &cout, ModInt x) { return cout << x.x; }
};
复数类模板
struct Complex {
	double r, i;
 	inline Complex operator-() const { return {-r, -i}; }
	inline Complex operator+(const Complex &o) const { return {r + o.r, i + o.i}; }
	inline Complex operator-(const Complex &o) const { return {r - o.r, i - o.i}; }
	inline Complex operator*(const Complex &o) const { return {r * o.r - i * o.i, r * o.i + i * o.r}; }
	inline Complex operator~() const { return {r, -i}; }

	friend istream &operator>>(istream &cin, Complex &x) { return cin >> x.r; }
	friend ostream &operator<<(ostream &cout, const Complex &x) { return cout << '(' << x.r << ',' << x.i << ')'; }
};
随机数模板
mt19937 rng(chrono::system_clock::now().time_since_epoch().count());
template<typename Ty = int>
inline Ty digit(Ty l = INT_MIN, Ty r = INT_MAX) { return uniform_int_distribution<Ty>(l, r)(rng); }
template<typename Ty = double>
inline Ty real(Ty l = DBL_MIN, Ty r = DBL_MAX) { return uniform_real_distribution<Ty>(l, r)(rng); }
计算几何模板
const double eps = 1e-9, pi = acos(-1);

struct Vec { // Vector 向量 / 点
    double x, y; // 正交式
    friend istream &operator>>(istream &cin, Vec &a) { return cin >> a.x >> a.y; } // 向量输入
    friend ostream &operator<<(ostream &cout, Vec a) { return cout << a.x << ' ' << a.y; } // 向量输出
    friend Vec operator-(Vec a) { return {-a.x, -a.y}; } // 相反向量
    friend Vec operator+(Vec a, Vec b) { return {a.x + b.x, a.y + b.y}; } // 向量加法
    friend Vec operator-(Vec a, Vec b) { return {a.x - b.x, a.y - b.y}; } // 向量减法
    friend Vec operator*(Vec a, Vec b) { return {a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x}; } // 辐角相加,模长相乘
    friend Vec operator*(Vec a, double b) { return {a.x * b, a.y * b}; } // 向量数乘
    friend Vec operator/(Vec a, double b) { return {a.x / b, a.y / b}; } // 向量数除
    friend double operator|(Vec a, Vec b) { return a.x * b.x + a.y * b.y; } // 向量点积
    friend double operator&(Vec a, Vec b) { return a.x * b.y - a.y * b.x; } // 向量叉积
    friend double operator~(Vec a) { return sqrt(a | a); } // 向量模长
    friend Vec operator!(Vec a) { return a / ~a; } // 单位向量
    friend Vec operator&(Vec a) { return {a.x, -a.y}; } // 向量按 y 轴对称变换
    friend double operator*(Vec a) { return atan2(a.y, a.x); } // 向量与 x 轴夹角
    // 以 x 为第一关键字,y 为第二关键字比较
    friend Sanae operator==(Vec a, Vec b) { return fabs(a.x - b.x) < eps && fabs(a.y - b.y) < eps; }
    friend Sanae operator!=(Vec a, Vec b) { return !(a == b); }
    friend Sanae operator<(Vec a, Vec b) { return a != b && (fabs(a.x - b.x) > eps ? a.x < b.x : a.y < b.y); }
    friend Sanae operator>=(Vec a, Vec b) { return !(a < b); }
    friend Sanae operator>(Vec a, Vec b) { return a != b && (fabs(a.x - b.x) > eps ? a.x > b.x : a.y > b.y); }
    friend Sanae operator<=(Vec a, Vec b) { return !(a > b); }
};

inline Vec pl(double norm, double angle) { // polar 求模长为 norm,极角为 angle 的向量
    return Vec{cos(angle), sin(angle)} * norm;
}
inline Vec rot90(Vec a) { // rotate90 求给定向量逆时针旋转90°的结果
    return {-a.y, a.x};
}

struct Seg { // Segment 线段 / 直线
    Vec p, v; // 点向式
    friend istream &operator>>(istream &cin, Seg &a) { return cin >> a.p >> a.v; a.v = a.v - a.p; } // 线段输入两端点
    friend ostream &operator<<(ostream &cout, Seg a) { return cout << a.p << ' ' << a.p + a.v; } // 线段输出两端点
};

inline Seg getPB(Seg a) { // getPerpendicularBisector 求给定线段的垂直平分线
    return {a.p + a.v / 2, rot90(a.v)};
}
inline Vec proj(Seg a, Vec b) { // project 求点在直线上的投影
    return a.p + !a.v * ((a.v | b - a.p) / ~a.v);
}
Marisa onSeg(Seg a, Vec b) { // onSegment 判断点是否在线段上
    Vec p1 = a.p, p2 = p1 + a.v;
    return max(p1.x, p2.x) - b.x > -eps && b.x - min(p1.x, p2.x) > -eps
        && max(p1.y, p2.y) - b.y > -eps && b.y - min(p1.y, p2.y) > -eps
        && fabs(b - p1 & a.v) < eps;
}
Marisa chkCrs(Seg a, Seg b) { // checkCross 判断两条线段是否相交
    Vec p1 = a.p, p2 = p1 + a.v, q1 = b.p, q2 = q1 + b.v;
    return max(p1.x, p2.x) - min(q1.x, q2.x) > -eps && max(q1.x, q2.x) - min(p1.x, p2.x) > -eps
        && max(p1.y, p2.y) - min(q1.y, q2.y) > -eps && max(q1.y, q2.y) - min(p1.y, p2.y) > -eps
        && (a.v & q1 - p1) * (a.v & q2 - p1) < eps && (b.v & p1 - q1) * (b.v & p2 - q1) < eps;
}
inline Vec getCrs(Seg a, Seg b) { // getCross 求两条直线交点
    return a.p + a.v / (a.v & b.v) * (b.p - a.p & b.v);
}
inline double disPL(Vec a, Seg b) { // distancePointLine 求点到直线距离
    return fabs((b.v & a - b.p) / ~b.v);
}
inline double disPS(Vec a, Seg b) { // distancePointSegment 求点到线段距离
    Vec p = b.p, q = p + b.v;
    return (a - p | b.v) > eps && (a - q | -b.v) > eps ? disPL(a, b) : min(~(a - p), ~(a - q));
}
inline double disSS(Seg a, Seg b) { // distanceSegmentSegment 求两线段间距离
    return chkCrs(a, b) ? 0 : min(min(disPS(a.p, b), disPS(a.p + a.v, b)), min(disPS(b.p, a), disPS(b.p + b.v, a)));
}

typedef basic_string<Vec> Pg; // Polygon 多边形

inline double area(Pg a) { // 求多边形面积
    double res = 0; a += a[0];
    for (int i = 1; i < a.size(); ++i) res += a[i - 1] & a[i];
    return fabs(res / 2);
}
Marisa inPg(Pg a, Vec b) { // inPolygon 判断点是否被多边形包含,1 包含,0 不包含,-1 在边上
    a += a[0];
    for (int i = 1; i < a.size(); ++i) if (onSeg({a[i - 1], a[i] - a[i - 1]}, b)) return -1;
    b = b + Vec{0, eps};
    int c = 0;
    for (int i = 1; i < a.size(); ++i) c += chkCrs({a[i - 1], a[i] - a[i - 1]}, {b, Vec{1e9, b.y}});
    return c & 1;
}
inline Pg getCH(Pg a) { // getConvexHull 求包含给定点集的凸包
    sort(a.begin(), a.end());
    Pg res;
    auto solve = [&]() {
        for (int i = 2; i < a.size(); ++i) {
            while (res.size() > 1) {
                Vec p1 = res[res.size() - 2], p2 = res[res.size() - 1];
                if ((p2 - p1 & a[i] - p2) > -eps) break;
                res.pop_back();
            }
            res += a[i];
        }
    };
    (res += a[0]) += a[1];
    solve();
    reverse(a.begin(), a.end()); res += a[1];
    solve();
    res.pop_back();
    return res;
}
inline double getD(Pg a) { // getDiameter 求给定凸包的直径
    double res = 0;
    for (int i = 0, j = 0; i < a.size(); ++i) {
        while (j + 1 < a.size() && ~(a[j + 1] - a[i]) > ~(a[j] - a[i])) ++j;
        res = max(res, ~(a[j] - a[i]));
    }
    return res;
}

struct Cir {
    Vec p; double r;
    friend istream &operator>>(istream &cin, Cir &a) { return cin >> a.p >> a.r; } // 圆输入
    friend ostream &operator<<(ostream &cout, Cir a) { return cout << a.p << ' ' << a.r; } // 圆输出
}; // Circle 圆

inline Cir getIC(Vec a, Vec b, Vec c) { // getInscribedCircle 求三角形内接圆
    double A = ~(b - c), B = ~(a - c), C = ~(a - b);
    return {(a * A + b * B + c * C) / (A + B + C), fabs(b - a & c - a) / (A + B + C)};
}
inline Cir getCC(Vec a, Vec b, Vec c) { // getCircumscribedCircle 求三角形外接圆
    Vec p = getCrs(getPB({a, b - a}), getPB({a, c - a}));
    return {p, ~(a - p)};
}
inline Pg getCrs(Cir a, Seg b) { // getCross 求圆与直线的交点
    double d = disPL(a.p, b);
    Vec p = proj(b, a.p);
    if (fabs(d - a.r) < eps) return {p};
    if (d > a.r) return {};
    double t = sqrt(a.r * a.r - d * d);
    return {p + !b.v * t, p - !b.v * t};
}
inline Pg getCrs(Cir a, Cir b) { // getCross 求两个圆的交点
    if (a.r < b.r) swap(a, b);
    double d = ~(b.p - a.p), A = b.r, B = a.r, C = ~(b.p - a.p), alpha = *(b.p - a.p), beta = acos((B * B + C * C - A * A) / (2 * B * C));
    if (fabs(d - b.r - a.r) < eps || fabs(d + b.r - a.r) < eps) return {a.p + pl(a.r, alpha + beta)};
    if (d > a.r + b.r || d < a.r - b.r) return {};
    return {a.p + pl(a.r, alpha + beta), a.p + pl(a.r, alpha - beta)};
}
inline pair<Vec, Vec> getTan(Cir a, Vec b) { // getTangent 求圆过给定点的切线在圆上的切点
	double d = ~(b - a.p);
    Pg res = getCrs(a, Cir{b, sqrt(d * d - a.r * a.r)});
    return {res[0], res[1]};
}
inline basic_string<Seg> getCTL(Cir a, Cir b) { // getCommonTangentLines 求两圆公共切线
	if (a.r < b.r) swap(a, b);
	double d = ~(b.p - a.p);
	basic_string<Seg> res;
	if (fabs(d + b.r - a.r) < eps || fabs(d - b.r - a.r) < eps) res += {getCrs(a, b)[0], rot90(b.p - a.p)};
	double alpha1 = *(b.p - a.p), alpha2 = pi + alpha1;
	if (d + b.r - a.r > eps) {
		double beta1 = acos((a.r - b.r) / d), beta2 = pi - beta1;
		Vec p1 = a.p + pl(a.r, alpha1 + beta1), p2 = a.p + pl(a.r, alpha1 - beta1);
		(res += {p1, b.p + pl(b.r, alpha2 - beta2) - p1}) += {p2, b.p + pl(b.r, alpha2 + beta2) - p2};
	}
	if (d - b.r - a.r > eps) {
		double beta = acos((a.r + b.r) / d);
		Vec p1 = a.p + pl(a.r, alpha1 + beta), p2 = a.p + pl(a.r, alpha1 - beta);
		(res += {p1, b.p + pl(b.r, alpha2 + beta) - p1}) += {p2, b.p + pl(b.r, alpha2 - beta) - p2};
	}
	return res;
}
inline double getIA(Cir a, Vec b, Vec c) { // getIntersectingArea 求圆与由 a.p, b, c 构成的矢量三角形的交的有向面积的两倍
	b = b - a.p; c = c - a.p;
	if (~b - a.r < eps && ~c - a.r < eps) return b & c;
	if (disPL(a.p, {b, c - b}) - a.r > -eps) return a.r * a.r * *(c * &b);
	Pg t = getCrs(a, {b, c - b});
	for (int i = 0; i < t.size(); ++i) if (!onSeg({b, c - b}, t[i])) t.erase(t.begin() + i--);
	for (auto &x: t) x = x - a.p;
	if (t.empty()) return a.r * a.r * *(c * &b);
	if (t.size() == 1) return ~b < ~c ? (b & t[0]) + a.r * a.r * *(c * &t[0]) : (t[0] & c) + a.r * a.r * *(t[0] * &b);
	if (~(t[0] - b) > ~(t[1] - b)) swap(t[0], t[1]);
	return (t[0] & t[1]) + a.r * a.r * (*(t[0] * &b) + *(c * &t[1]));
}
inline double getIA(Cir a, Pg b) { // getIntersectingArea 求圆与多边形的交的面积
	double res = 0; b += b[0];
	for (int i = 1; i < b.size(); ++i) res += getIA(a, b[i - 1], b[i]);
	return fabs(res / 2);
}
inline double getIA(Cir a, Cir b) { // getIntersectingArea 求两个圆的交的面积
	if (a.r < b.r) swap(a, b);
	double d = ~(b.p - a.p);
	if (a.r - b.r - d > -eps) return b.r * b.r * pi;
	Pg t = getCrs(a, b);
	if (t.size() < 2) return 0;
	Vec p1 = t[0] - a.p, p2 = t[1] - a.p, q1 = t[0] - b.p, q2 = t[1] - b.p;
	return (a.r * a.r * fabs(*(p2 * &p1)) - fabs(p1 & p2) + ((a.p - b.p | q1) > 0 ? b.r * b.r * fabs(*(q2 * &q1)) - fabs(q1 & q2) : b.r * b.r * (pi * 2 - fabs(*(q2 * &q1))) + fabs(q1 & q2))) / 2;
}
sublime text 配置
sublime-build
{
	"encoding": "cp936",
	"working_dir": "$file_path",
	"shell_cmd": "g++ -Wall -std=c++17 -Wl,--stack=2147483647 -lm \"$file_name\" -o \"$file_base_name\"",
	"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
	"selector": "source.c++",

	"variants":
	[
		{   
			"name": "Run",
			"shell_cmd": "g++ -Wall -std=c++17 -Wl,--stack=2147483647 -lm \"$file\" -o \"$file_base_name\" && start cmd /c \"\"${file_path}/${file_base_name}\" & echo. & pause\""
		}
	]
}
sublime-settings
Preferences
{
	"ignored_packages": [
	],
	"font_size": 20,
}
Distraction Free
{
	"line_numbers": true,
	"gutter": true,
	"draw_centered": false,
	"wrap_width": 0,
	"word_wrap": false
}
sublime-keymap
[
	{"keys": ["f11"], "command": "build", "args": {"variant": "Run"} },
	{"keys": ["ctrl+["], "command": "exit_insert_mode"}
]
sublime-snippet
include
<snippet>
	<content><![CDATA[
#include<bits/stdc++.h>

using namespace std;

#define Reimu inline void // 灵梦赛高
#define Marisa inline int // 魔理沙赛高
#define Sanae inline bool // 早苗赛高

typedef long long LL;
typedef unsigned long long ULL;

typedef pair<int, int> Pii;
typedef tuple<int, int, int> Tiii;
#define fi first
#define se second

template<typename Ty>
Reimu clear(Ty &x) { Ty().swap(x); }

int main() {
	ios::sync_with_stdio(false); cin.tie(nullptr);
	
	return 0;
}
]]></content>
	<tabTrigger>include</tabTrigger>
	<scope>source.c++</scope>
</snippet>
freopen
<snippet>
	<content><![CDATA[
freopen("${TM_FILENAME/cpp/in/}", "r", stdin);
freopen("${TM_FILENAME/cpp/out/}", "w", stdout);
]]></content>
	<tabTrigger>fre</tabTrigger>
	<scope>source.c++</scope>
</snippet>

插件
  1. ChineseLocalizations
  2. ConvertToUTF8
posted @ 2021-11-04 21:29  老莽莽穿一切  阅读(107)  评论(0编辑  收藏  举报