代码头
#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>
插件
- ChineseLocalizations
- ConvertToUTF8