You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2629 lines
72 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"C++模板初始化": {
"prefix": "cpp",
"body": [
"#include <bits/stdc++.h>",
"using namespace std;",
"#define endl '\\n'",
"int main() {",
" // 加快读入",
" ios::sync_with_stdio(false), cin.tie(0);",
" $1",
" return 0;",
"}"
],
"description": "C++模板文件"
},
"定义长整型为整型": {
"prefix": "ill",
"body": [
"#define int long long"
"#define endl \"\\n\""
]
},
"C++模板初始化2": {
"prefix": "init",
"body": [
"#include <bits/stdc++.h>",
"",
"using namespace std;",
"#define int long long",
"signed main() {",
" $1",
"}"
]
},
"快读": {
"prefix": "read",
"description": "快读",
"body": [
"//快读",
"LL read() {",
" LL x = 0, f = 1;",
" char ch = getchar();",
" while (ch < '0' || ch > '9') {",
" if (ch == '-') f = -1;",
" ch = getchar();",
" }",
" while (ch >= '0' && ch <= '9') {",
" x = (x << 3) + (x << 1) + (ch ^ 48);",
" ch = getchar();",
" }",
" return x * f;",
"}",
]
},
"快读快写": {
"prefix": "rw",
"body": [
"//快读快写",
"LL read() {",
" LL x = 0, f = 1;",
" char ch = getchar();",
" while (ch < '0' || ch > '9') {",
" if (ch == '-') f = -1;",
" ch = getchar();",
" }",
" while (ch >= '0' && ch <= '9') {",
" x = (x << 3) + (x << 1) + (ch ^ 48);",
" ch = getchar();",
" }",
" return x * f;",
"}",
"void write(LL x) {",
" if (x < 0) putchar('-'), x = -x;",
" if (x > 9) write(x / 10);",
" putchar(x % 10 + '0');",
"}"
]
},
"快读快写2": {
"prefix": "rw2",
"description": "快读快写",
"body": [
"//快读快写",
"char buf[1 << 23], *p1 = buf, *p2 = buf;",
"#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)",
"int read() {",
" int x = 0, f = 1;",
" char ch = getchar();",
" while (ch < '0' || ch > '9') {",
" if (ch == '-') f = -1;",
" ch = getchar();",
" }",
" while (ch >= '0' && ch <= '9') {",
" x = (x << 3) + (x << 1) + (ch ^ 48);",
" ch = getchar();",
" }",
" return x * f;",
"}",
"void write(int x) {",
" if (x < 0) putchar('-'), x = -x;",
" if (x > 9) write(x / 10);",
" putchar(x % 10 + '0');",
"}",
]
},
"readn": {
"prefix": "rn",
"body": "n = read();"
},
"readm": {
"prefix": "rm",
"body": "m = read();"
},
"readnm": {
"prefix": "rnm",
"body": "n = read(), m = read();"
},
"readx": {
"prefix": "rx",
"body": "x = read();"
},
"ready": {
"prefix": "ry",
"body": "y = read();"
},
"readxy": {
"prefix": "rxy",
"body": "x = read(), y = read();"
},
"reada": {
"prefix": "ra",
"body": "a = read();"
},
"readb": {
"prefix": "rb",
"body": "b = read();"
},
"readab": {
"prefix": "rab",
"body": "a = read(), b = read();"
},
"中国剩余定理": {
"prefix": "CRT",
"body": [
"int n; // 同余方程个数",
"int m[N]; // 除数数组",
"int r[N]; // 余数数组",
"LL M = 1; // 除数累乘积",
"LL x, y; // (x,y)是方程 Mi * x + m[i] * y = 1的一个解x是Mi关于m[i]的逆元",
"LL res; // 最小整数解",
"// 扩展欧几里得模板",
"LL exgcd(LL a, LL b, LL &x, LL &y) {",
" if (!b) {",
" x = 1, y = 0;",
" return a;",
" }",
" LL d = exgcd(b, a % b, y, x);",
" y -= a / b * x;",
" return d;",
"}",
"",
"// 中国剩余定理模板",
"void CRT() {",
" // 一、预处理",
" for (int i = 1; i <= n; i++) {",
" cin >> m[i] >> r[i]; // 读入除数数组和余数数组",
" r[i] = (r[i] % m[i] + m[i]) % m[i]; // ① 预算余数为正数: r[i]可能为负数,预处理成正数,本题没有这个要求,但考虑到通用模板,加上了这块代码",
" M *= m[i]; // ② 预处理除数连乘积",
" }",
" // 二、计算",
" // 功能: 求 x ≡ r_i mod m_i 方程组的解",
" for (int i = 1; i <= n; i++) {",
" LL Mi = M / m[i]; // ①除数连乘积除去当前的除数得到Mi",
" exgcd(Mi, m[i], x, y); // ②扩欧求逆元",
" x = (x % m[i] + m[i]) % m[i]; // ③逆元防负数",
" res = (res + r[i] * Mi * x) % M; // ④累加res看公式",
" }",
"}"
]
},
"四连通": {
"prefix": "dx4",
"description": "四连通",
"body": [
"int dx[] = {-1, 0, 1, 0}; //上右下左",
"int dy[] = {0, 1, 0, -1}; //上右下左",
],
},
"八连通": {
"prefix": "dx8",
"description": "八连通",
"body": [
"//8个方向",
"int dx[] = {0, 0, -1, 1, -1, 1, -1, 1}; //上下左右",
"int dy[] = {1, -1, 0, 0, 1, 1, -1, -1}; //左下,右下,左上,右上",
""
]
},
"二分": {
"prefix": "ef",
"body": [
"int lower_bound(int q[], int l, int r, int x) {",
" while (l < r) {",
" int mid = (l + r) >> 1;",
" if (q[mid] >= x)",
" r = mid;",
" else",
" l = mid + 1;",
" }",
" return l;",
"}",
"int upper_bound(int q[], int l, int r, int x) {",
" while (l < r) {",
" int mid = (l + r) >> 1;",
" if (q[mid] > x)",
" r = mid;",
" else",
" l = mid + 1;",
" }",
" return l;",
"}",
"",
""
]
},
"lower_bound": {
"prefix": "ef1",
"body": [
"//手写二分模板,左闭右开",
"int l = 0, r = idx;",
"int mid = (l + r) >> 1;",
"if (q[mid] >= x)",
" r = mid;",
"else",
" l = mid + 1;",
]
},
"upper_bound": {
"prefix": "ef2",
"body": [
"//手写二分模板,左闭右开",
"int l = 0, r = idx;",
"int mid = (l + r) >> 1;",
"if (q[mid] > x)",
" r = mid;",
"else",
" l = mid + 1;",
]
},
"扩展欧几里得": {
"prefix": "exgcd",
"description": "扩展欧几里得",
"body": [
"",
"//扩展欧几里得",
"LL exgcd(LL a, LL b, LL &x, LL &y) {",
" if (!b) {",
" x = 1, y = 0;",
" return a;",
" }",
" LL d = exgcd(b, a % b, y, x);",
" y -= a / b * x;",
" return d;",
"}"
]
},
"斐波那契数列": {
"prefix": "fib",
"description": "斐波那契数列",
"body": [
"typedef long long LL;",
"const int N = 21;",
"LL a[N];",
"/*",
" a[1] = 1;",
" a[2] = 2;",
" for (int i = 3; i < N; i++)",
" a[i] = a[i - 1] + a[i - 2];",
" for (int i = 1; i < N; i++)",
" printf(\"%lld \", a[i]);",
" */"
]
},
"01背包": {
"prefix": "bb01",
"description": "01背包",
"body": [
"#include<bits/stdc++.h>",
"",
"using namespace std;",
"const int N = 1010;",
"",
"int n, m;",
"int v[N], w[N];",
"int f[N];",
"",
"int main() {",
" //物品个数n",
" scanf(\"%d%d\",&n,&m);",
" //读入体积和重量",
" for (int i = 1; i <= n; i++) scanf(\"%d%d\",&v[i],&w[i]);",
" //01背包模板",
" for (int i = 1; i <= n; i++)",
" for (int j = m; j >= v[i]; j--)",
" f[j] = max(f[j], f[j - v[i]] + w[i]);",
"",
" cout << f[m] << endl;",
" return 0;",
"}"
]
},
"二维费用01背包": {
"prefix": "bb01erwei",
"body": [
"#include <bits/stdc++.h>",
"",
"using namespace std;",
"const int N = 1010;",
"const int M = 110;",
"int n, V, W;",
"int v1[N], v2[N], w[N];",
"int f[N][M][M];",
"",
"int main() {",
" cin >> n >> V >> W;",
" for (int i = 1; i <= n; i++) cin >> v1[i] >> v2[i] >> w[i];",
" for (int i = 1; i <= n; i++)",
" for (int j = 0; j <= V; j++)",
" for (int k = 0; k <= W; k++)",
" if (j < v1[i] || k < v2[i])",
" f[i][j][k] = f[i - 1][j][k];",
" else",
" f[i][j][k] = max(f[i - 1][j - v1[i]][k - v2[i]] + w[i], f[i - 1][j][k]);",
" printf(\"%d\", f[n][V][W]);",
" return 0;",
"}"
],
"description": "二维费用01背包",
},
"完全背包": {
"prefix": "bbwq",
"description": "完全背包",
"body": [
"#include <bits/stdc++.h>",
"",
"using namespace std;",
"",
"const int N = 1010;",
"",
"int n, m;",
"int v[N];",
"int w[N];",
"int f[N];",
"",
"// 完全背包问题",
"int main() {",
" scanf(\"%d%d\",&n,&m);",
" for (int i = 1; i <= n; i++) scanf(\"%d%d\",&v[i],&w[i]);",
"",
" for (int i = 1; i <= n; i++)",
" for (int j = v[i]; j <= m; j++) //一个一个加上来,求一个最大值",
" f[j] = max(f[j], f[j - v[i]] + w[i]);",
"",
" cout << f[m] << endl;",
" return 0;",
"}"
]
},
"多重背包I": {
"prefix": "bbdc1",
"description": "多重背包I",
"body": [
"#include <bits/stdc++.h>",
"",
"using namespace std;",
"",
"//多重背包问题每件物品的数量是有限制的不是无穷也不是只有1个。",
"// 状态表示 集合,属性",
"// 状态计算",
"",
"const int N = 110;",
"",
"int n, m;",
"int v[N], w[N], s[N];",
"int f[N];",
"",
"int main() {",
" scanf(\"%d%d\",&n,&m);",
" for (int i = 1; i <= n; i++) cin >> scanf(\"%d%d%d\",&v[i],&w[i],&s[i]);",
"",
" for (int i = 1; i <= n; i++)",
" for (int j = m; j >= 0; j--)",
" for (int k = 0; k <= s[i] && k * v[i] <= j; k++) //穷举所有可能性,尝试拿到最大的合理值",
" f[j] = max(f[j], f[j - v[i] * k] + w[i] * k);",
"",
" cout << f[m] << endl;",
" return 0;",
"}"
]
},
"多重背包II": {
"prefix": "bbdc2",
"description": "多重背包II",
"body": [
"#include <bits/stdc++.h>",
"",
"using namespace std;",
"const int N = 12010, M = 2010;",
"",
"int n, m;",
"int v[N], w[N];",
"int f[M];",
"",
"//多重背包的二进制优化",
"int main() {",
" scanf(\"%d%d\",&n,&m);",
" int cnt = 0;",
" for (int i = 1; i <= n; i++) {",
" int a, b, s;",
" scanf(\"%d%d%d\",&a,&b,&s);",
" //二进制优化,能打包则打包之1,2,4,8,16,...",
" int k = 1;",
" while (k <= s) {",
" cnt++;",
" v[cnt] = a * k;",
" w[cnt] = b * k;",
" s -= k;",
" k *= 2;",
" }",
" //剩下的",
" if (s > 0) {",
" cnt++;",
" v[cnt] = a * s;",
" w[cnt] = b * s;",
" }",
" }",
" n = cnt;//数量减少啦",
" //01背包",
" for (int i = 1; i <= n; i++)",
" for (int j = m; j >= v[i]; j--)",
" f[j] = max(f[j], f[j - v[i]] + w[i]);",
"",
" cout << f[m] << endl;",
" return 0;",
"}"
]
},
"多重背包之单调队列优化": {
"prefix": "bbdc3",
"body": [
"#include <bits/stdc++.h>",
"",
"using namespace std;",
"",
"const int N = 1010;",
"const int M = 20010;",
"int n, m;",
"int v[N], w[N], s[N];",
"int f[N][M];",
"int q[M];",
"//多重背包之单调队列优化",
"int main() {",
" scanf(\"%d%d\",&n,&m);",
" for (int i = 1; i <= n; i++) scanf(\"%d%d%d\",&v[i],&w[i],&s[i]);",
"",
" for (int i = 1; i <= n; i++)",
" for (int r = 0; r < v[i]; r++) {",
" int hh = 0, tt = -1;",
" for (int j = r; j <= m; j += v[i]) {",
" while (hh <= tt && j - q[hh] > s[i] * v[i]) hh++;",
" while (hh <= tt && f[i - 1][q[tt]] + (j - q[tt]) / v[i] * w[i] <= f[i - 1][j]) tt--;",
" q[++tt] = j;",
" f[i][j] = f[i - 1][q[hh]] + (j - q[hh]) / v[i] * w[i];",
" }",
" }",
" printf(\"%d\", f[n][m]);",
" return 0;",
"}",
""
],
"description": "多重背包之单调队列优化"
},
"分组背包": {
"prefix": "bbfz",
"description": "分组背包",
"body": [
"#include <bits/stdc++.h>",
"",
"using namespace std;",
"const int N = 110;",
"",
"int n; //n类物品",
"int m; //背包上限为m",
"int v[N][N]; //价值",
"int w[N][N]; //体积",
"int s[N]; //个数",
"int f[N]; //dp数组最大值",
"",
"//分组背包",
"int main() {",
" scanf(\"%d%d\",&n,&m);",
"",
" for (int i = 1; i <= n; i++) {//枚举每类物品,比如:水果,蔬菜,肉类...",
" scanf(\"%d\",&s[i]); //此类物品中物品的个数,比如2可能是苹果、香蕉",
" for (int j = 1; j <= s[i]; j++)//读入苹果、香蕉的价值和体积",
" scanf(\"%d%d\",&v[i][j],&w[i][j])",
" }",
"",
" for (int i = 1; i <= n; i++) //遍历每类物品",
" for (int j = m; j >= 0; j--) //遍历每个可能的体积",
" for (int k = 1; k <= s[i]; k++)//遍历第k个物品",
" if (v[i][k] <= j)",
" f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);",
"",
" cout << f[m] << endl;",
" return 0;",
"}"
]
},
"欧几里得求最大公约数": {
"prefix": "gcd",
"description": "欧几里得求最大公约数",
"body": [
"//最大公约数,辗转相除法",
"int gcd(int a, int b) {",
" return b ? gcd(b, a % b) : a;",
"}",
""
]
},
"欧拉筛": {
"prefix": "ols",
"description": "欧拉筛",
"body": [
"//欧拉筛",
"const int N = 1e5 + 10;",
"int primes[N], cnt; // primes[]存储所有素数",
"bool st[N]; // st[x]存储x是否被筛掉",
"void get_primes(int n) {",
" for (int i = 2; i <= n; i++) {",
" if (!st[i]) primes[cnt++] = i;",
" for (int j = 0; primes[j]*i <= n; j++) {",
" st[primes[j] * i] = true;",
" if (i % primes[j] == 0) break;",
" }",
" }",
"}",
"/*",
" get_primes(200);",
" for (int i = 0; i < cnt; i++)",
" if (primes[i] > 100) ",
"cout << primes[i] << \" \";",
"*/"
]
},
"埃拉筛": {
"prefix": "als",
"description": "埃拉筛",
"body": [
"const int N = 1e5 + 10;",
"int primes[N], cnt; // primes[]存储所有素数",
"bool st[N]; // st[x]存储x是否被筛掉",
"//埃拉筛",
"void get_primes(int n) {",
" for (int i = 2; i <= n; i++)",
" if (!st[i]) {",
" primes[cnt++] = i; //记录素数",
" for (int j = 2 * i; j <= n; j += i) //成倍数的标识",
" st[j] = true;",
" }",
"}",
"/*",
" get_primes(200);",
" for (int i = 0; i < cnt; i++)",
" if (primes[i] > 100) ",
"cout << primes[i] << \" \";",
"*/"
]
},
"回文数": {
"prefix": "hws",
"description": "回文数",
"body": [
"//判断回文数",
"bool isHWS(int num) {",
" int t = num, ans = 0;",
" while (t) {",
" ans = ans * 10 + t % 10;",
" t /= 10;",
" }",
" return ans == num;",
"}",
""
]
},
"质数": {
"prefix": "isPrime",
"description": "质数",
"body": [
"//判断一个数是不是质数",
"bool isPrime(int n) {",
" if (n < 2) return false;",
" for (int i = 2; i <= n / i; i++)",
" if (n % i == 0) return false;",
" return true;",
"}",
"/*",
" for (int i = 100; i <= 200; i++)",
" if (isPrime(i)) cout << i << \" \";",
"*/",
""
]
},
"最小公倍数": {
"prefix": "lcm",
"description": "最小公倍数",
"body": [
"//最小公倍数",
"int lcm(int a, int b) {",
" return a * b / gcd(a, b);",
"}"
]
},
"水仙花数": {
"prefix": "sxh",
"description": "水仙花数",
"body": [
"//是不是水仙花数",
"bool isSXH(int n) {",
" int s = 0, m;",
" m = n;",
" while (m) {",
" int a = m % 10;",
" s += a * a * a;",
" m /= 10;",
" }",
" return s == n;",
"}"
]
},
"完数": {
"prefix": "wms",
"description": "完数",
"body": [
"//完数",
"int isWMS(int n) {",
" int s = 0;",
" for (int i = 1; i <= n / 2; i++)",
" if (n % i == 0) s += i;",
"",
" return s == n ? 1 : 0;",
"}",
"/*",
" 用法:",
" for (int i = 1; i <= 1000; i++)",
" if (isWMS(i)) cout << i << \" \";",
" return 0;",
"*/"
]
},
"闰年": {
"prefix": "runnian",
"description": "闰年",
"body": [
"int months_1[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};",
"int months_2[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};",
"",
"bool LeapYear(int year) {",
" return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);",
"}",
"/*",
"用法:",
"int main() {",
" int y, m, d, days = 0;",
" cin >> y >> m >> d;",
" if (LeapYear(y)) {",
" for (int i = 1; i <= m - 1; i++)",
" days += months_2[i];",
" days += d;",
" } else {",
" for (int i = 1; i <= m - 1; i++)",
" days += months_1[i];",
" days += d;",
" }",
" cout << days << endl;",
" return 0;",
"}",
"*/"
]
},
"长整数": {
"description": "长整数",
"prefix": "ll",
"body": [
"typedef long long LL;",
]
},
"无符号长整数": {
"description": "无符号长整数",
"prefix": "ull",
"body": [
"typedef unsigned long long ULL;"
]
},
"INT128": {
"description": "INT128,NOIP可用不想打高精度的福音",
"prefix": "lll",
"body": [
"typedef __int128 LLL; ",
]
},
"快速i0循环": {
"prefix": "fori0",
"body": [
"for (int i = 0; i < $1; i++)"
],
"description": "快速i0循环"
},
"快速j0循环": {
"prefix": "forj0",
"body": [
"for (int j = 0; j < $1; j++)"
],
"description": "快速j0循环"
},
"快速k0循环": {
"prefix": "fork0",
"body": [
"for (int k = 0; k < $1; k++)",
],
"description": "快速k0循环"
},
"快速n0循环": {
"prefix": "forn0",
"body": [
"for (int i = 0; i < n; i++)",
],
"description": "快速n0循环"
},
"快速m0循环": {
"prefix": "form0",
"body": [
"for (int i = 0; i < m; i++)"
],
"description": "快速m0循环"
},
"快速i1循环": {
"prefix": "fori1",
"body": [
"for (int i = 1; i <= $1; i++)",
],
"description": "快速i1循环"
},
"快速j1循环": {
"prefix": "forj1",
"body": [
"for (int j = 1; j <= $1; j++)",
],
"description": "快速j1循环"
},
"快速k1循环": {
"prefix": "fork1",
"body": [
"for (int k = 1; k <= $1; k++)",
],
"description": "快速k1循环"
},
"快速n1循环": {
"prefix": "forn1",
"body": [
"for (int i = 1; i <= n; i++)",
],
"description": "快速n1循环"
},
"快速m1循环": {
"prefix": "form1",
"body": [
"for (int i = 1; i <= m; i++)",
],
"description": "快速m1循环"
},
"从文件读入数据": {
"prefix": "fre",
"body": [
"//配置从文本文件读入数据",
"#ifndef ONLINE_JUDGE",
"freopen(\"in.txt\",\"r\", stdin);",
"#endif",
],
"description": "从文件读入数据"
},
"记录程序运行时间": {
"prefix": "sj",
"body": [
"//记录开始时间",
"clock_t begin = clock();",
"$1",
"//记录结束时间",
"clock_t end = clock();",
"cout << \"Running time:\" << (double)(end - begin) / CLOCKS_PER_SEC * 1000 << \"ms\" << endl;"
],
"description": "记录程序运行时间"
},
"整数数对PII带x,y": {
"description": "整数数对PII",
"prefix": "piixy",
"body": [
"typedef pair<int, int> PII;",
"#define x first",
"#define y second",
]
},
"整数数对PII": {
"description": "整数数对PII",
"prefix": "pii",
"body": [
"typedef pair<int, int> PII;",
]
},
"双级数对": {
"prefix": "piii",
"body": [
"#define x first",
"#define y second",
"typedef pair<int, pair<int, int>> PIII;",
],
"description": "双级数对"
},
"无穷大": {
"prefix": "inf",
"body": [
"const int INF = 0x3f3f3f3f;",
],
"description": "无穷大"
},
"万能头文件": {
"prefix": "stdc",
"body": [
"#include <bits/stdc++.h>",
],
"description": "万能头文件"
},
"Dijkstra算法": {
"prefix": "dijkstra",
"body": [
"const int N = 10010, M = N * 2;",
"typedef pair<int, int> PII;",
"//邻接表",
"int h[N], e[M], w[M], ne[M], idx;",
"void add(int a, int b, int c) {",
" e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;",
"}",
"int d[N]; //最短距离数组",
"bool st[N]; //是否进过队列",
"//迪杰斯特拉",
"void dijkstra(int start) {",
" memset(d, 0x3f, sizeof d); //初始化距离为无穷大",
" memset(st, 0, sizeof st); //初始化为未出队列过",
" priority_queue<PII, vector<PII>, greater<PII>> q; //小顶堆",
" q.push({0,start}); //出发点入队列",
" d[start] = 0; //出发点距离0",
" while (q.size()) {",
" auto t = q.top();",
" q.pop();",
" int u = t.second;",
" if (st[u]) continue;",
" st[u] = true;",
" for (int i = h[u]; ~i; i = ne[i]) {",
" int j = e[i];",
" if (d[j] > d[u] + w[i]) {",
" d[j] = d[u] + w[i];",
" q.push({d[j], j});",
" }",
" }",
" }",
"}"
],
"description": "Dijkstra"
},
"SPFA算法": {
"prefix": "spfa",
"body": [
"int h[N], e[M], w[M], ne[M], idx;",
"void add(int a, int b, int c) {",
" e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;",
"}",
"int dist[N];",
"bool st[N]; ",
"",
"// spfa模板",
"void spfa(int S) {",
" queue<int> q;",
" memset(dist, 0x3f, sizeof dist);",
" dist[S] = 0;",
"",
" q.push(S); ",
" st[S] = true;",
"",
" while (q.size()) {",
" int u = q.front();",
" q.pop();",
" st[u] = false;",
" for (int i = h[u]; ~i; i = ne[i]) {",
" int j = e[i];",
" if (dist[j] > dist[u] + w[i]) {",
" dist[j] = dist[u] + w[i];",
" if (!st[j]) {",
" st[j] = true;",
" q.push(j);",
" }",
" }",
" }",
" }",
"}"
],
"description": "SPFA算法"
},
"SPFA_SLF优化算法": {
"prefix": "spfa_slf",
"body": [
"bool st[N]; //是不是在队列中",
"int dist[N]; //最短距离数组",
"int e[M], h[N], idx, w[M], ne[M];",
"void add(int a, int b, int c) {",
" e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;",
"}",
"void spfa(int S) {",
" deque<int> q; //双端队列",
" memset(dist, 0x3f, sizeof dist);",
" memset(st, false, sizeof(st));",
" st[S] = true;",
" q.push_back(S);",
" dist[S] = 0;",
"",
" while (q.size()) {",
" int t = q.front();",
" q.pop_front();",
" st[t] = false;",
" for (int i = h[t]; ~i; i = ne[i]) {",
" int j = e[i];",
" if (dist[j] > dist[t] + w[i]) {",
" dist[j] = dist[t] + w[i];",
" if (!st[j]) {",
" st[j] = true;",
" if (q.size() && dist[q.front()] > dist[j])",
" q.push_front(j);",
" else",
" q.push_back(j);",
" }",
" }",
" }",
" }",
"}"
],
"description": "SPFA优化版本"
},
"弗洛伊德求多源最短路": {
"prefix": "floyd",
"body": [
"// Floyd算法模板",
"for (int k = 0; k < n; k++)",
" for (int i = 0; i < n; i++)",
" for (int j = 0; j < n; j++)",
" d[i][j] = min(d[i][j], d[i][k] + d[k][j]);"
],
"description": "Floyd算法模板"
},
"O2优化": {
"prefix": "o2",
"body": [
"#pragma GCC optimize(2) //累了就吸点氧吧~"
],
"description": "开启O2优化"
},
"链式前向星": {
"prefix": "ljb",
"body": [
"// 初始化链式前向星",
"memset(h, -1, sizeof h);",
"//链式前向星",
"int e[M], h[N], idx, w[M], ne[M];",
"void add(int a, int b, int c = 0) {",
" e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;",
"}"
],
"description": "链式前向星"
},
"二维一维互转": {
"prefix": "pos",
"body": [
"//二维转一维的办法,坐标从(1,1)开始",
"int get(int x, int y) {",
" return (x - 1) * m + y;",
"}",
"//一维转二维的办法,坐标从(1,1)开始",
"int get(int &x, int &y, int z) {",
" x = (z - 1) / m + 1;",
" y = (z - 1) % m + 1;",
"}"
]
},
"Prim算法": {
"prefix": "prim",
"body": [
"",
"const int INF = 0x3f3f3f3f;",
"const int N = 510;",
"int n, m; //点和边",
"int g[N][N]; //稠密图,邻接矩阵",
"int dist[N]; //这个点到集合的距离",
"bool st[N]; //是不是已经使用过",
"int res; //最小生成树里面边的长度之和",
"",
"int prim() {",
" cin >> n >> m;",
" memset(g, 0x3f, sizeof g); //初始化图",
" memset(dist, 0x3f, sizeof dist); //初始化离集合最短距离",
" while (m--) {",
" int a, b, c;",
" cin >> a >> b >> c;",
" g[a][b] = g[b][a] = min(g[a][b], c);",
" }",
" // prim算法的精髓:每次都要把剩余点和生成树的最小距离重新求出来。",
" for (int i = 0; i < n; i++) {",
" int t = -1;",
" for (int j = 1; j <= n; j++)",
" if (!st[j] && (t == -1 || dist[t] > dist[j])) t = j;",
" if (i && dist[t] == INF) return INF;",
" if (i) res += dist[t];",
" for (int j = 1; j <= n; j++) dist[j] = min(dist[j], g[t][j]);",
" st[t] = true;",
" }",
" return res;",
"}"
],
"description": "Prim算法求最小生成树"
},
"Kruskal算法": {
"prefix": "kruskal",
"body": [
"",
"const int INF = 0x3f3f3f3f;",
"int n, m; // n条顶点,m条边",
"int res; //最小生成树的权值和",
"int cnt; //组成最小生成树的结点数",
"// Kruskal用到的结构体",
"const int N = 100010, M = N << 1;",
"struct Edge {",
" int a, b, w;",
" bool operator<(const Edge &W) const {",
" return w < W.w;",
" }",
"} e[M];",
"//并查集",
"int p[N];",
"int find(int x) {",
" if (x == p[x]) return x;",
" return p[x] = find(p[x]);",
"}",
"// Kruskal算法",
"int kruskal() {",
" cin >> n >> m;",
" for (int i = 0; i < m; i++) {",
" int a, b, w;",
" cin >> a >> b >> w;",
" e[i] = {a, b, w};",
" }",
" //按边的权重排序",
" sort(e, e + m);",
" // 初始化并查集",
" for (int i = 1; i <= n; i++) p[i] = i;",
" //枚举每条边",
" for (int i = 0; i < m; i++) {",
" int a = e[i].a, b = e[i].b, w = e[i].w;",
" a = find(a), b = find(b);",
" if (a != b)",
" p[a] = b, res += w, cnt++;",
" }",
" //如果不连通",
" if (cnt < n - 1) return INF;",
" return res;",
"}"
],
"description": "Kruskal算法"
},
"最简并查集": {
"prefix": "bcj",
"body": [
"//最简并查集",
"int p[N];",
"int find(int x) {",
" if (x == p[x]) return x;",
" return p[x] = find(p[x]);",
"}",
"//合并集合",
"bool join(int a, int b) {",
" if (find(a) == find(b)) return false;",
" p[find(a)] = find(b);",
" return true;",
"}",
"//初始化并查集",
"void init() {",
" for (int i = 0; i < N; i++) p[i] = i;",
"}"
],
"description": "最简并查集"
},
"带权并查集": {
"prefix": "bcjdq",
"body": [
"//带边权更新并查集模板",
"int find(int x) {",
" if (x == p[x]) return x;",
" int root = find(p[x]);",
" d[x] += d[p[x]];",
" return p[x] = root;",
"}"
],
"description": "带权并查集"
},
"无序离散化": {
"prefix": "lshwx",
"body": [
"//无序离散化",
"unordered_map<int, int> S;",
"int get(int x) {",
" if (S.count(x) == 0) S[x] = ++n; // x映射为第n个数字",
" return S[x];",
"}"
],
"description": "无序离散化"
},
"lowbit x异或-x": {
"body": "#define lowbit(x) (x & -x)",
"prefix": "lowbit",
"description": "lowbit 不用解释了吧~"
},
"树状数组": {
"prefix": "szsz",
"body": [
"// 树状数组模板",
"typedef long long LL;",
"#define lowbit(x) (x & -x)",
"int c[N];",
"void add(int x, int d) {",
" for (int i = x; i < N; i += lowbit(i)) c[i] += d;",
"}",
"LL sum(int x) {",
" LL res = 0;",
" for (int i = x; i; i -= lowbit(i)) res += c[i];",
" return res;",
"}"
]
},
"多个树状数组": {
"prefix": "mszsz",
"body": [
"// 树状数组模板",
"int c1[N], c2[N];",
"",
"#define lowbit(x) (x & -x)",
"typedef long long LL;",
"",
"void add(int c[], int x, int d) {",
" for (int i = x; i < N; i += lowbit(i)) c[i] += d;",
"}",
"",
"LL sum(int c[], int x) {",
" LL res = 0;",
" for (int i = x; i; i -= lowbit(i)) res += c[i];",
" return res;",
"}"
]
},
"线段树区间和": {
"prefix": "xdsqjh",
"body": [
"// 线段树模板",
"#define int long long",
"#define ls u << 1",
"#define rs u << 1 | 1",
"#define mid ((l + r) >> 1)",
"struct Node {",
" int l, r;",
" int sum, add; // 区间总和,累加懒标记",
"} tr[N << 2];",
"",
"// 更新统计信息",
"void pushup(int u) {",
" tr[u].sum = tr[ls].sum + tr[rs].sum;",
"}",
"",
"void pushdown(int u) {",
" if (tr[u].add == 0) return;",
" tr[ls].add += tr[u].add;",
" tr[rs].add += tr[u].add;",
" tr[ls].sum += (tr[ls].r - tr[ls].l + 1) * tr[u].add;",
" tr[rs].sum += (tr[rs].r - tr[rs].l + 1) * tr[u].add;",
" tr[u].add = 0; // 清除懒标记",
"}",
"",
"// 构建",
"void build(int u, int l, int r) {",
" tr[u].l = l, tr[u].r = r; // 标记范围",
" if (l == r) { // 叶子",
" cin >> tr[u].sum; // 区间内只有一个元素l(r),区间和为read(),不需要记录向下的传递tag",
" return;",
" }",
" build(ls, l, mid), build(rs, mid + 1, r); // 左右儿子构建",
" pushup(u); // 通过左右儿子构建后,向祖先节点反馈统计信息变化",
"}",
"",
"// 区间所有元素加上v",
"void modify(int u, int L, int R, int v) {",
" int l = tr[u].l, r = tr[u].r;",
" if (l >= L && r <= R) { // 如果完整被覆盖",
" tr[u].sum += (r - l + 1) * v;",
" tr[u].add += v;",
" return;",
" }",
" if (l > R || r < L) return; // 如果没有交集",
" pushdown(u); // 下传懒标记",
" modify(ls, L, R, v), modify(rs, L, R, v); // 修改左,修改右",
" pushup(u); // 向上汇报统计信息",
"}",
"",
"// 查询",
"int query(int u, int L, int R) {",
" int l = tr[u].l, r = tr[u].r;",
" if (l >= L && r <= R) return tr[u].sum; // 如果完整被覆盖",
" if (l > R || r < L) return 0; // 如果没有交集",
" pushdown(u); // 下传懒标记",
" return query(ls, L, R) + query(rs, L, R); // 查询左+查询右",
"}",
"// 构建线段树",
"// build(1, 1, n);"
]
},
"动态开点线段树": {
"prefix": "xdsdtkd",
"body": [
"// 动态开点线段树",
"#define int long long",
"#define ls tr[u].l",
"#define rs tr[u].r",
"#define mid ((l + r) >> 1)",
"struct Node {",
" int l, r;",
" int sum, add;",
"} tr[N << 2];",
"",
"int root, idx;",
"// 根节点编号初始值是0通过modify创建第1个也就是根root=1",
"// idx:节点号游标",
"",
"// 汇总统计信息",
"void pushup(int u) {",
" tr[u].sum = tr[ls].sum + tr[rs].sum;",
"}",
"",
"void pushdown(int &u, int l, int r) {",
" if (tr[u].add == 0) return; // 如果没有累加懒标记,返回",
" if (ls == 0) ls = ++idx; // 左儿子创建",
" if (rs == 0) rs = ++idx; // 右儿子创建",
" // 懒标记下传",
" tr[ls].sum += tr[u].add * (mid - l + 1); // 区间和增加=懒标记 乘以 区间长度",
" tr[rs].sum += tr[u].add * (r - mid);",
" tr[ls].add += tr[u].add; // 加法的懒标记可以叠加",
" tr[rs].add += tr[u].add;",
" // 清除懒标记",
" tr[u].add = 0;",
"}",
"",
"// 区间修改",
"void modify(int &u, int l, int r, int L, int R, int v) {",
" if (u == 0) u = ++idx; // 动态开点",
"",
" if (l >= L && r <= R) { // 如果区间被完整覆盖",
" tr[u].add += v; // 加法的懒标记可以叠加",
" tr[u].sum += v * (r - l + 1); // 区间和增加=懒标记 乘以 区间长度",
" return;",
" }",
" if (l > R || r < L) return; // 如果没有交集",
"",
" // 下传懒标记",
" pushdown(u, l, r);",
" // 分裂",
" modify(ls, l, mid, L, R, v), modify(rs, mid + 1, r, L, R, v);",
" // 汇总",
" pushup(u);",
"}",
"",
"// 区间查询",
"int query(int u, int l, int r, int L, int R) {",
" if (l >= L && r <= R) return tr[u].sum; // 如果完整命中,返回我的全部",
" if (l > R || r < L) return 0; // 如果与我无关,返回0",
" pushdown(u, l, r);",
" return query(ls, l, mid, L, R) + query(rs, mid + 1, r, L, R);",
"}"
]
},
"线段树求最大值模板": {
"prefix": "xdsmax",
"body": [
"//线段树求最大值模板",
"struct Node {",
" int l, r, v; // 区间[l, r]中的最大值v",
"} tr[N << 2]; // 开4倍空间",
"",
"void pushup(int u) {",
" tr[u].v = max(tr[u << 1].v, tr[u << 1 | 1].v);",
"}",
"",
"void build(int u, int l, int r) {",
" tr[u] = {l, r};",
" if (l == r) return;",
" int mid = (l + r) >> 1;",
" build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);",
"}",
"",
"int query(int u, int l, int r) {",
" if (tr[u].l >= l && tr[u].r <= r) return tr[u].v;",
" int mid = (tr[u].l + tr[u].r) >> 1;",
" int v = 0;",
" if (l <= mid) v = query(u << 1, l, r);",
" if (r > mid) v = max(v, query(u << 1 | 1, l, r));",
" return v;",
"}",
"",
"void modify(int u, int x, int v) {",
" if (tr[u].l == tr[u].r) {",
" tr[u].v = v;",
" return;",
" }",
" int mid = (tr[u].l + tr[u].r) >> 1;",
" if (x <= mid)",
" modify(u << 1, x, v);",
" else",
" modify(u << 1 | 1, x, v);",
" pushup(u);",
"}"
]
},
"三个数字取最大值": {
"prefix": "max",
"body": [
"//三个数字取最大值",
"int max(int a, int b, int c) {",
" return max(a, max(b, c));",
"}"
],
"description": "三个数字取最大值"
},
"cin录入n": {
"prefix": "cinn",
"body": "cin >> n;",
"description": "录入n"
},
"cin录入m": {
"prefix": "cinm",
"body": "cin >> m;",
"description": "录入m"
},
"cin录入k": {
"prefix": "cink",
"body": "cin >> k;",
"description": "录入k"
},
"cin录入m1m2n": {
"prefix": "cinm1m2n",
"body": "cin >> m1 >> m2;",
"description": "录入m1m2n"
},
"cin录入nm1m2": {
"prefix": "cinnm1m2",
"body": "cin >> n >> m1 >> m2;",
"description": "录入nm1m2"
},
"cin录入x": {
"prefix": "cinx",
"body": "cin >> x;",
"description": "录入x"
},
"cin录入y": {
"prefix": "ciny",
"body": "cin >> y;",
"description": "录入y"
},
"cin录入xy": {
"prefix": "cinxy",
"body": "cin >> x >> y;",
"description": "录入xy"
},
"cin录入T": {
"prefix": "cint",
"body": "cin >> T;",
"description": "录入T"
},
"cin录入t": {
"prefix": "cint2",
"body": "cin >> t;",
"description": "录入t"
},
"cin录入a": {
"prefix": "cina",
"body": "cin >> a;",
"description": "录入a"
},
"cin录入a,b": {
"prefix": "cinab",
"body": "cin >> a >> b;",
"description": "录入a,b"
},
"cin录入a,b,c": {
"prefix": "cinabc",
"body": "cin >> a >> b >> c;",
"description": "录入a,b,c"
},
"cin录入a,b,w": {
"prefix": "cinabw",
"body": "cin >> a >> b >> w;",
"description": "录入a,b,w"
},
"cin录入n,m参数": {
"prefix": "cinnm",
"body": "cin >> n >> m;",
"description": "录入2个参数"
},
"cin录入p,q参数": {
"prefix": "cinpq",
"body": "cin >> p >> q;",
"description": "录入p,q 2个参数"
},
"cin录入p参数": {
"prefix": "cinp",
"body": "cin >> p;",
"description": "录入p参数"
},
"cin录入q参数": {
"prefix": "cinq",
"body": "cin >> q;",
"description": "录入q参数"
},
"cin录入m,n参数": {
"prefix": "cinmn",
"body": "cin >> m >> n;",
"description": "录入m,n,2个参数"
},
"cin录入n,m,k个参数": {
"prefix": "cinnmk",
"body": "cin >> n >> m >> k;",
"description": "录入n,m,k个参数"
},
"cin录入n,k个参数": {
"prefix": "cinnk",
"body": "cin >> n >> k;",
"description": "录入n,k个参数"
},
"cin录入c": {
"prefix": "cinc",
"body": "cin >> c;",
"description": "录入c"
},
"cin录入a[i,j]": {
"prefix": "cinaij",
"body": "cin >> a[i][j]",
"description": "录入a[i][j]"
},
"cin录入a[i]": {
"prefix": "cinai",
"body": "cin >> a[i];",
"description": "录入a[i]"
},
"cin录入s[i]": {
"prefix": "cinsi",
"body": "cin >> s[i];",
"description": "录入s[i]"
},
"cin录入s[i][j]": {
"prefix": "cinsij",
"body": "cin >> s[i][j];",
"description": "录入s[i][j]"
},
"cin录入v[i]": {
"prefix": "cinvi",
"body": "cin >> v[i];",
"description": "录入v[i]"
},
"cin录入w[i]": {
"prefix": "cinwi",
"body": "cin >> w[i];",
"description": "录入w[i]"
},
"cin录入vw[i]": {
"prefix": "cinvwi",
"body": "cin >> v[i] >> w[i];",
"description": "录入vw[i]"
},
"cin录入vw": {
"prefix": "cinvw",
"body": "cin >> v[i] >> w[i];",
"description": "录入vw"
},
"cin录入vws": {
"prefix": "cinvws",
"body": "cin >> v[i] >> w[i] >> s[i]",
"description": "录入vws"
},
"cin录入wv[i]": {
"prefix": "cinwvi",
"body": "cin >> w[i] >> v[i]",
"description": "录入wv[i]"
},
"cin录入wvs[i]": {
"prefix": "cinwvs",
"body": "cin >> w[i] >> v[i] >> s[i];",
"description": "录入wvs[i]"
},
"cin录入w[i][j]": {
"prefix": "cinwij",
"body": "cin >> w[i][j];",
"description": "录入w[i][j]"
},
"cin录入q[i]": {
"prefix": "cinqi",
"body": "cin >> q[i];",
"description": "录入q[i]"
},
"cin录入q[i][j]": {
"prefix": "cinqij",
"body": "cin >> q[i][j];",
"description": "录入q[i][j]"
},
"cin录入b[i,j]": {
"prefix": "cinbij",
"body": "cin",
"description": "录入b[i][j]"
},
"cin录入b[i]": {
"prefix": "cinbi",
"body": "cin >> b[i];",
"description": "录入b[i]"
},
"录入n": {
"prefix": "scn",
"body": "scanf(\"%d\", &n);",
"description": "录入n"
},
"录入m": {
"prefix": "scm",
"body": "scanf(\"%d\", &m);",
"description": "录入m"
},
"录入k": {
"prefix": "sck",
"body": "scanf(\"%d\", &k);",
"description": "录入k"
},
"录入m1m2n": {
"prefix": "scm1m2n",
"body": "scanf(\"%d %d %d\", &m1, &m2, &n);",
"description": "录入m1m2n"
},
"录入nm1m2": {
"prefix": "scnm1m2",
"body": "scanf(\"%d %d %d\", &n, &m1, &m2);",
"description": "录入nm1m2"
},
"录入x": {
"prefix": "scx",
"body": "scanf(\"%d\", &x);",
"description": "录入x"
},
"录入y": {
"prefix": "scy",
"body": "scanf(\"%d\", &y);",
"description": "录入y"
},
"录入xy": {
"prefix": "scxy",
"body": "scanf(\"%d %d\", &x ,&y);",
"description": "录入xy"
},
"录入T": {
"prefix": "sct",
"body": "scanf(\"%d\", &T);",
"description": "录入T"
},
"录入t": {
"prefix": "sct2",
"body": "scanf(\"%d\", &t);",
"description": "录入t"
},
"录入a": {
"prefix": "sca",
"body": "scanf(\"%d\", &a);",
"description": "录入a"
},
"录入a,b": {
"prefix": "scab",
"body": "scanf(\"%d %d\", &a, &b);",
"description": "录入a,b"
},
"录入a,b,c": {
"prefix": "scabc",
"body": "scanf(\"%d %d %d\", &a, &b, &c);",
"description": "录入a,b,c"
},
"录入a,b,w": {
"prefix": "scabw",
"body": "scanf(\"%d %d %d\", &a, &b, &w);",
"description": "录入a,b,w"
},
"录入n,m参数": {
"prefix": "scnm",
"body": "scanf(\"%d %d\", &n, &m);",
"description": "录入2个参数"
},
"录入p,q参数": {
"prefix": "scpq",
"body": "scanf(\"%d %d\", &p, &q);",
"description": "录入p,q 2个参数"
},
"录入p参数": {
"prefix": "scp",
"body": "scanf(\"%d\", &p);",
"description": "录入p参数"
},
"录入q参数": {
"prefix": "scq",
"body": "scanf(\"%d\", &q);",
"description": "录入q参数"
},
"录入m,n参数": {
"prefix": "scmn",
"body": "scanf(\"%d %d\", &m, &n);",
"description": "录入m,n,2个参数"
},
"录入n,m,k个参数": {
"prefix": "scnmk",
"body": "scanf(\"%d %d %d\", &n, &m, &k);",
"description": "录入n,m,k个参数"
},
"录入n,k个参数": {
"prefix": "scnk",
"body": "scanf(\"%d %d\", &n, &k);",
"description": "录入n,k个参数"
},
"录入不确定的整数值": {
"prefix": "sc",
"body": "scanf(\"%d\", &$1);",
"description": "录入不确定的整数值"
},
"录入不确定的长整数值1": {
"prefix": "scl",
"body": "scanf(\"%lld\", &$1);",
"description": "录入不确定的长整数值1"
},
"录入不确定的整数值1": {
"prefix": "sc1",
"body": "scanf(\"%d\", &$1);",
"description": "录入不确定的整数值1"
},
"录入不确定的整数值2": {
"prefix": "sc2",
"body": "scanf(\"%d %d\", &$1,&$2);",
"description": "录入不确定的整数值2"
},
"录入不确定的整数值3": {
"prefix": "sc3",
"body": "scanf(\"%d %d %d\", &$1,&$2,&$3);",
"description": "录入不确定的整数值3"
},
"录入不确定的整数值4": {
"prefix": "sc4",
"body": "scanf(\"%d %d %d %d\", &$1,&$2,&$3,&$4);",
"description": "录入不确定的整数值4"
},
"录入不确定的整数值5": {
"prefix": "sc5",
"body": "scanf(\"%d %d %d %d %d\", &$1,&$2,&$3,&$4,&$5);",
"description": "录入不确定的整数值5"
},
"录入不确定的整数值6": {
"prefix": "sc6",
"body": "scanf(\"%d %d %d %d %d %d\", &$1,&$2,&$3,&$4,&$5,&$6);",
"description": "录入不确定的整数值6"
},
"录入c": {
"prefix": "scc",
"body": "scanf(\"%d\", &c);",
"description": "录入c"
},
"录入nLong": {
"prefix": "scln",
"body": "scanf(\"%lld\", &n);",
"description": "录入nLong"
},
"录入aLong": {
"prefix": "scla",
"body": "scanf(\"%lld\", &a);",
"description": "录入aLong"
},
"录入aLong,bLong": {
"prefix": "sclab",
"body": "scanf(\"%lld %lld\", &a, &b);",
"description": "录入aLong,bLong"
},
"录入aLong,bLong,cLong": {
"prefix": "sclabc",
"body": "scanf(\"%lld %lld %lld\", &a, &b, &c);",
"description": "录入aLong,bLong,cLong"
},
"录入nLong,mLong参数": {
"prefix": "sclnm",
"body": "scanf(\"%lld %lld\", &n, &m);",
"description": "录入nLong,mLong"
},
"录入nLong,mLong,kLong参数": {
"prefix": "scnlmk",
"body": "scanf(\"%lld %lld %lld\", &n, &m, &k);",
"description": "录入nLong,mLong,kLong参数"
},
"录入a[i,j]": {
"prefix": "scaij",
"body": "scanf(\"%d\", &a[i][j]);",
"description": "录入a[i][j]"
},
"录入a[i]": {
"prefix": "scai",
"body": "scanf(\"%d\", &a[i]);",
"description": "录入a[i]"
},
"录入s[i]": {
"prefix": "scsi",
"body": "scanf(\"%d\", &s[i]);",
"description": "录入s[i]"
},
"录入s[i][j]": {
"prefix": "scsij",
"body": "scanf(\"%d\", &s[i][j]);",
"description": "录入s[i][j]"
},
"录入v[i]": {
"prefix": "scvi",
"body": "scanf(\"%d\", &v[i]);",
"description": "录入v[i]"
},
"录入w[i]": {
"prefix": "scwi",
"body": "scanf(\"%d\", &w[i]);",
"description": "录入w[i]"
},
"录入vw[i]": {
"prefix": "scvwi",
"body": "scanf(\"%d %d\",&v[i], &w[i]);",
"description": "录入vw[i]"
},
"录入vw": {
"prefix": "scvw",
"body": "scanf(\"%d %d\",&v, &w);",
"description": "录入vw"
},
"录入vws": {
"prefix": "scvws",
"body": "scanf(\"%d %d %d\",&v, &w ,&s);",
"description": "录入vws"
},
"录入wv[i]": {
"prefix": "scwvi",
"body": "scanf(\"%d %d\",&w[i], &v[i]);",
"description": "录入wv[i]"
},
"录入wvs[i]": {
"prefix": "scwvsi",
"body": "scanf(\"%d %d %d\", &vw[i], &v[i], &s);",
"description": "录入wvs[i]"
},
"录入w[i][j]": {
"prefix": "scwij",
"body": "scanf(\"%d\", &w[i][j]);",
"description": "录入w[i][j]"
},
"录入q[i]": {
"prefix": "scqi",
"body": "scanf(\"%d\", &q[i]);",
"description": "录入w[i]"
},
"录入q[i][j]": {
"prefix": "scqij",
"body": "scanf(\"%d\", &q[i][j]);",
"description": "录入q[i][j]"
},
"录入b[i,j]": {
"prefix": "scbij",
"body": "scanf(\"%d\", &b[i][j]);",
"description": "录入b[i][j]"
},
"录入b[i]": {
"prefix": "scbi",
"body": "scanf(\"%d\", &b[i]);",
"description": "录入b[i]"
},
"输出数字": {
"prefix": "pt",
"body": "printf(\"%d \",$1);",
"description": "输出数字,不换行"
},
"输出1": {
"prefix": "pn",
"body": "printf(\"%d\\n\",$1);",
"description": "输出数字1"
},
"输出2": {
"prefix": "pn2",
"body": "printf(\"%d %d\\n\",$1,);",
"description": "输出数字2"
},
"输出3": {
"prefix": "pn3",
"body": "printf(\"%d %d %d\\n\",$1, ,);",
"description": "输出数字3"
},
"输出Long1": {
"prefix": "pln",
"body": "printf(\"%lld\\n\",$1);",
"description": "输出数字1Long"
},
"输出2Long": {
"prefix": "pl2n",
"body": "printf(\"%lld %lld\\n\",$1,);",
"description": "输出数字2Long"
},
"输出3Long": {
"prefix": "pl3n",
"body": "printf(\"%lld %lld %lld\\n\",$1, ,);",
"description": "输出数字3Long"
},
"输入常量N": {
"prefix": "conn",
"body": "const int N = 1010;",
"description": "输入常量N"
},
"Tarjan算法求强连通分量": {
"prefix": "tarjan",
"description": "Tarjan算法求强连通分量",
"body": [
"// Tarjan算法求强连通分量",
"int dfn[N], low[N];",
"int stk[N], top;",
"bool in_stk[N];",
"int timestamp;",
"int scc;",
"void init_tarjan(int n) {",
" timestamp = scc = top = 0;",
" memset(in_stk, false, sizeof(in_stk));",
" memset(dfn, 0, sizeof(dfn));",
"}",
"void tarjan(int u) {",
" dfn[u] = low[u] = ++timestamp;",
" stk[++top] = u;",
" in_stk[u] = true;",
" for (int i = h[u]; ~i; i = ne[i]) {",
" int j = e[i];",
" if (!dfn[j]) {",
" tarjan(j);",
"",
" low[u] = min(low[u], low[j]);",
" } else if (in_stk[j])",
" low[u] = min(low[u], low[j]);",
" }",
"",
" if (dfn[u] == low[u]) {",
" ++scc;",
" int x;",
" do {",
" x = stk[top--];",
" in_stk[x] = false;",
" } while (x != u);",
" }",
"}",
"// 调用示例",
"// for (int i = 0; i < n; i++)",
"// if (!dfn[i]) tarjan(i);"
]
},
"快速幂":{"prefix":"qmi","body": [
"// 快速幂",
"int qmi(int a, int b, int p) {",
" int res = 1;",
" a %= p;",
" while (b) {",
" if (b & 1) res = res * a % p;",
" b >>= 1;",
" a = a * a % p;",
" }",
" return res;",
"}",
""]},
"龟速乘": {
"prefix": "qmul",
"body": [
"//龟速乘",
"int qmul(int a, int b, int p) {",
" int res = 0;",
" while (b) {",
" if (b & 1) res = (res + a) % p;",
" a = (a + a) % p;",
" b >>= 1;",
" }",
" return res;",
"}"
],
"description": "龟速乘"
},
"矩阵乘法与快速幂": {
"prefix": "jzmul",
"body": [
"//矩阵乘法",
"void mul(int a[][N], int b[][N], int c[][N]) {",
" int t[N][N] = {0};",
" for (int i = 0; i < N; ++i) {",
" for (int j = 0; j < N; ++j)",
" for (int k = 0; k < N; ++k)",
" t[i][j] = (t[i][j] + (LL)(a[i][k] * b[k][j]) % mod) % mod;",
" }",
" memcpy(c, t, sizeof t);",
"}",
"",
"",
"/*",
"// f:base case或者单位矩阵",
"// a:需要计算快速幂的常数矩阵 ",
"// f:结果存储",
"int f[N][N] = {1}; ",
"//矩阵快速幂",
"for (int i = n; i; i >>= 1) {",
" if (i & 1) mul(f, a, f); // f(3)=f(1)*a(2)",
" mul(a, a, a); // 倍增a",
"}",
"*/"
],
"description": "矩阵乘法与快速幂"
},
"加快读入": {
"prefix": "sync",
"body": [
"//加快读入",
"ios::sync_with_stdio(false), cin.tie(0);",
],
"description": "加快读入"
},
"加快读入2": {
"prefix": "sync2",
"body": [
"//加快读入",
"ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);",
],
"description": "加快读入"
},
"高斯消元求解线性方程组": {
"prefix": "gauss",
"body": [
"const double eps = 1e-8;",
"double a[N][N];",
"",
"int gauss() {",
" int c, r;",
" for (c = 0, r = 0; c < n; c++) {",
" int t = r;",
" for (int i = r; i < n; i++)",
" if (abs(a[i][c]) > abs(a[t][c])) t = i;",
"",
" if (abs(a[t][c]) < eps) continue;",
"",
" if (r != t) swap(a[t], a[r]);",
"",
" for (int i = n; i >= c; i--) a[r][i] /= a[r][c];",
"",
" for (int i = r + 1; i < n; i++)",
" for (int j = n; j >= c; j--)",
" a[i][j] -= a[r][j] * a[i][c];",
" r++;",
" }",
"",
" if (r < n) {",
" for (int i = r; i < n; i++)",
" if (abs(a[i][n]) > eps)",
" return 2;",
" return 1;",
" }",
"",
" for (int i = n - 2; i >= 0; i--)",
" for (int j = i + 1; j < n; j++)",
" a[i][n] -= a[i][j] * a[j][n];",
"",
" return 0;",
"}",
"/*",
"调用示例:",
"for (int i = 0; i < n; i++)",
" for (int j = 0; j <= n; j++)",
" cin >> a[i][j];",
"",
"int t = gauss();",
"if (t == 2)",
" puts(\"No solution\");",
"else if (t == 1)",
" puts(\"Infinite group solutions\");",
"else {",
" for (int i = 0; i < n; i++) {",
" if (abs(a[i][n]) < eps) a[i][n] = 0;",
" printf(\"%.2lf\n\", a[i][n]);",
" }",
"}",
"*/"
]
},
"高斯消元求解异或线性方程组": {
"prefix": "gaussxor",
"body": [
"int a[N][N];",
"void gauss() {",
" int c, r;",
" for (c = 0, r = 0; c < n; c++) {",
" int t = r;",
"",
" for (int i = r; i < n; i++)",
" if (a[i][c]) {",
" t = i;",
" break;",
" }",
"",
" if (!a[t][c]) continue;",
"",
" if (r != t) swap(a[r], a[t]);",
"",
" for (int i = r + 1; i < n; i++)",
" if (a[i][c])",
" for (int j = n; j >= c; j--)",
" a[i][j] ^= a[r][j];",
"",
" r++;",
" }",
" if (r < n) {",
" for (int i = r; i < n; i++)",
" if (a[i][n]) {",
" puts(\"No solution\");",
" exit(0);",
" }",
"",
" puts(\"Multiple sets of solutions\");",
" exit(0);",
" }",
"",
" for (int i = n - 2; i >= 0; i--)",
" for (int j = i + 1; j < n; j++)",
" a[i][n] ^= a[i][j] * a[j][n];",
"}",
"/*",
"调用示例:",
"cin >> n;",
"for (int i = 0; i < n; i++)",
" for (int j = 0; j < n + 1; j++)",
" cin >> a[i][j];",
"",
"gauss();",
"",
"for (int i = 0; i < n; i++) cout << a[i][n] << endl;",
"*/"
]
},
"高精度加法": {
"prefix": "add",
"body": [
"const int N = 100010;",
"int a[N], b[N];",
"int al, bl;",
"void add(int a[], int &al, int b[], int &bl) {",
" int t = 0;",
" al = max(al, bl);",
" for (int i = 1; i <= al; i++) {",
" t += a[i] + b[i];",
" a[i] = t % 10;",
" t /= 10;",
" }",
" if (t) a[++al] = 1;",
"}",
"/*",
"用法:",
"for (int i = x.size() - 1; i >= 0; i--) a[++al] = x[i] - '0';",
"for (int i = y.size() - 1; i >= 0; i--) b[++bl] = y[i] - '0';",
"",
"add(a, al, b, bl);",
"for (int i = al; i; i--) printf(\"%d\", a[i]);",
"*/"
]
},
"高精度减法": {
"prefix": "sub",
"body": [
"const int N = 1e5 + 10;",
"int a[N], al;",
"int b[N], bl;",
"void sub(int a[], int &al, int b[], int &bl) {",
" int t = 0;",
" al = max(al, bl);",
" for (int i = 1; i <= al; i++) {",
" t = a[i] - b[i] - t;",
" a[i] = (t + 10) % 10;",
" t < 0 ? t = 1 : t = 0;",
" }",
" while (al > 1 && a[al] == 0) al--;",
"}",
"/*",
"用法",
"//负号",
"if (x.size() < y.size() || (x.size() == y.size() && x < y)) {",
" printf(\"-\");",
" swap(x, y);",
"}",
"",
"for (int i = x.size() - 1; i >= 0; i--) a[++al] = x[i] - '0';",
"for (int i = y.size() - 1; i >= 0; i--) b[++bl] = y[i] - '0';",
"",
"sub(a, al, b, bl);",
"for (int i = al; i >= 1; i--) printf(\"%d\", a[i]);",
"*/"
]
},
"高精乘低精": {
"prefix": "mul",
"body": [
"const int N = 1e5 + 10;",
"int a[N], al;",
"",
"void mul(int a[], int &al, int b) {",
" int t = 0;",
" for (int i = 1; i <= al; i++) {",
" t += a[i] * b;",
" a[i] = t % 10;",
" t /= 10;",
" }",
" while (t) {",
" a[++al] = t % 10;",
" t /= 10;",
" }",
" //去前导0",
" while (al > 1 && !a[al]) al--;",
"}",
"/*",
"用法",
"for (int i = x.size() - 1; i >= 0; i--) a[++al] = x[i] - '0';",
"mul(a, al, y);",
"",
"for (int i = al; i; i--) printf(\"%d\", a[i]);",
"*/"
]
},
"高精乘高精": {
"prefix": "mul2",
"body": [
"const int N = 1e5 + 10;",
"int a[N], al;",
"int b[N], bl;",
"void mul(int a[], int &al, int b[], int &bl) {",
" int t = 0;",
" int c[N] = {0};",
" for (int i = 1; i <= al; i++)",
" for (int j = 1; j <= bl; j++)",
" c[i + j - 1] += a[i] * b[j];",
" al += bl;",
" for (int i = 1; i <= al; i++) {",
" t += c[i];",
" a[i] = t % 10;",
" t /= 10;",
" }",
" // 前导0",
" while (al > 1 && a[al] == 0) al--;",
"}",
"/*",
"用法:",
"for (int i = x.size() - 1; i >= 0; i--) a[++al] = x[i] - '0';",
"for (int i = y.size() - 1; i >= 0; i--) b[++bl] = y[i] - '0';",
"",
"mul(a, al, b, bl);",
"for (int i = al; i; i--) printf(\"%d\", a[i]);",
"*/"
]
},
"高精度乘高精度限定K个长度":{
"prefix":"mulK",
"body": [
"const int N = 1e5 + 10;",
"int a[N], al;",
"int b[N], bl;",
"void mul(int a[], int &al, int b[], int &bl) {",
" int t = 0;",
" int c[N] = {0};",
" for (int i = 1; i <= al; i++)",
" for (int j = 1; j <= bl; j++)",
" c[i + j - 1] += a[i] * b[j];",
" al += bl;",
" al = min(al,K); ",
" for (int i = 1; i <= al; i++) {",
" t += c[i];",
" a[i] = t % 10;",
" t /= 10;",
" }",
" // 前导0",
" while (al > 1 && a[al] == 0) al--;",
"}",
"/*",
"用法:",
"for (int i = x.size() - 1; i >= 0; i--) a[++al] = x[i] - '0';",
"for (int i = y.size() - 1; i >= 0; i--) b[++bl] = y[i] - '0';",
"",
"mul(a, al, b, bl);",
"for (int i = al; i; i--) printf(\"%d\", a[i]);",
"*/"
]
},
"高精除低精": {
"prefix": "div",
"body": [
"const int N = 1e5 + 10;",
"int a[N], al, r;",
"void div(int a[], int &al, int b, int &r) {",
" r = 0;",
" for (int i = al; i >= 1; i--) {",
" r = r * 10 + a[i];",
" a[i] = r / b;",
" r %= b;",
" }",
" //去前导0",
" while (al > 1 && !a[al]) al--;",
"}",
"/*",
"用法:",
"for (int i = x.size() - 1; i >= 0; i--) a[++al] = x[i] - '0';",
"",
"div(a, al, y, r);",
"for (int i = al; i; i--) printf(\"%d\", a[i]);",
"*/"
]
},
"打印调试信息一维": {
"prefix": "debug1",
"body": [
" puts(\"**********************************************\");",
" for (int i = 1; i <= n; i++)",
" printf(\"%d \", a[i]);",
" puts(\"==============================================\");"
]
},
"打印调试信息二维": {
"prefix": "debug2",
"body": [
" puts(\"**********************************************\");",
" for (int i = 1; i <= n; i++, puts(\"\"))",
" for (int j = 1; j <= n; j++)",
" printf(\"%d \", f[i][j]);",
" puts(\"==============================================\");"
]
},
"初始化数组f为0": {
"prefix": "memf",
"body": [
"memset(f, 0, sizeof f);"
]
},
"初始化数组f为INF": {
"prefix": "memfinf",
"body": [
"memset(f, 0x3f, sizeof f);"
]
},
"初始化数组a为0": {
"prefix": "mema",
"body": [
"memset(a, 0, sizeof a);"
]
},
"初始化数组a为INF": {
"prefix": "memainf",
"body": [
"memset(a, 0x3f, sizeof a);"
]
},
"输入HASH": {
"prefix": "uii",
"body": [
"unordered_map<int, int> primes;"
],
"description": "输入HASH"
},
"输入①": {
"prefix": "n1",
"body": [
"①"
],
"description": "输入①"
},
"输入②": {
"prefix": "n2",
"body": [
"②"
],
"description": "输入②"
},
"输入③": {
"prefix": "n3",
"body": [
"③"
],
"description": "输入③"
},
"输入④": {
"prefix": "n4",
"body": [
"④"
],
"description": "输入④"
},
"输入⑤": {
"prefix": "n5",
"body": [
"⑤"
],
"description": "输入⑤"
},
"输入⑥": {
"prefix": "n6",
"body": [
"⑥"
],
"description": "输入⑥"
},
"输入⑦": {
"prefix": "n7",
"body": [
"⑦"
],
"description": "输入⑦"
},
"输入⑧": {
"prefix": "n8",
"body": [
"⑧"
],
"description": "输入⑧"
},
"输入⑨": {
"prefix": "n9",
"body": [
"⑨"
],
"description": "输入⑨"
},
"输入⑩": {
"prefix": "n10",
"body": [
"⑩"
],
"description": "输入⑩"
},
"输入1~6": {
"prefix": "n16",
"body": [
"① ② ③ ④ ⑤ ⑥"
]
},
"fin输入输出": {
"prefix": "fin",
"body": [
"#ifndef ONLINE_JUDGE",
" freopen(\"$1.in\", \"r\", stdin);",
" freopen(\"$2.out\", \"w\", stdout);",
"#endif"
]
},
"while循环": {
"prefix": "wh",
"body": "while($1)",
"description": "while循环"
},
"小数精度": {
"prefix": "eps",
"body": "const double eps = 1e-8;",
"description": "小数精度"
},
"结构体": {
"prefix": "node",
"body": [
"struct Node {",
" int id;",
" int value;",
" bool operator<(const Node &t) const {",
" if (value == t.value) return id < t.id;",
" return value < t.value;",
" }",
"} a[N];"
]
},
"MSI": {
"prefix": "msi",
"body": [
"typedef unordered_map<string, int> MSI;"
]
},
"MSP": {
"prefix": "msp",
"body": [
"typedef unordered_map<string, pair<char, string>> MSP;"
]
},
"lrson": {
"prefix": "lrson",
"body": [
"#define ls u << 1",
"#define rs u << 1 | 1"
]
},
"数位递增数": {
"prefix": "DiZengShu",
"body": [
"bool iSDiZeng(int x) {",
" int p = 10; //哨兵,前驱值",
" while (x) {",
" if (x % 10 > p) return false; //当前位大于上一数位,则不是数位递增数",
" p = x % 10;",
" x /= 10;",
" }",
" return true;",
"}"
]
},
"完美数": {
"prefix": "WMS",
"body": [
"int isWMS(int n) {",
" int s = 0;",
" for (int i = 1; i <= n / 2; i++)",
" if (n % i == 0) s += i;",
" return s == n;",
"}"
]
},
"属于": {
"prefix": "in",
"body": [
"∈"
]
},
"POJ文件头": {
"prefix": "POJ",
"body": [
"#include <iostream>",
"#include <algorithm>",
"#include <queue>",
"#include <map>",
"#include <cstring>",
"#include <vector>",
"#include <stack>",
"#include <cstdio>"
]
},
"离散化": {
"prefix": "lsh",
"body": [
" // 二分模板 lower_bound (左闭右开)",
" int find(int x) {",
" return lower_bound(q + 1, q + 1 + ql, x) - q;",
" }",
"// 离散化 = 排序+去重",
" sort(q + 1, q + n + 1);",
"",
" // 方法1 【很经典的静态数组原地离散化的套路代码】",
" // ql = 1; // 第一个元素肯定要保留下来",
" // for (int i = 2; i <= n; i++) // 放过头雁打二雁",
" // if (q[i] != q[ql]) q[++ql] = q[i]; // 如果连续一样的就放过如果发现不一样的就填充入离散化后的数组。在同一个数组上操作牛X",
"",
" // 方法2 【STL大法去重离散化】",
" ql = unique(q + 1, q + 1 + n) - q - 1;",
]
},
"树状数组求最大值模板": {
"prefix": "szszMax",
"body": [
"// 树状数组求最大值模板",
"int c[N];",
"int lowbit(int x) {",
" return x & -x;",
"}",
"void update(int x, int d) {",
" for (int i = x; i < N; i += lowbit(i)) c[i] = max(c[i], d);",
"}",
"",
"int query(int x, int y) {",
" int mx = 0;",
" while (x <= y) {",
" mx = max(mx, a[y]);",
" for (--y; y - x >= lowbit(y); y -= lowbit(y)) mx = max(mx, c[y]);",
" }",
" return mx;",
"}"
]
},
"线段树区间边界快速录入": {
"prefix": "xdsquick",
"body": [
"int l = tr[u].l, r = tr[u].r;",
"if (l > R || r < L) return;",
"if (l >= L && r <= R) {}"
]
},
"柯朵莉树模板": {
"prefix": "odt",
"body": [
"// 柯朵莉树模板",
"struct Node {",
" int l, r; // l和r表示这一段的起点和终点",
" mutable int v; // v表示这一段上所有元素相同的值是多少,注意关键字 mutable,使得set中结构体属性可修改",
" bool operator<(const Node &b) const {",
" return l < b.l; // 规定按照每段的左端点排序",
" }",
"};",
"set<Node> s; // 柯朵莉树的区间集合",
"",
"// 分裂:[l,x-1],[x,r]",
"set<Node>::iterator split(int x) {",
" auto it = s.lower_bound({x});",
" if (it != s.end() && it->l == x) return it; // 一击命中",
" it--; // 没有找到就减1个继续找",
" if (it->r < x) return s.end(); // 真的没找到,返回s.end()",
"",
" int l = it->l, r = it->r, v = it->v; // 没有被返回,说明找到了,记录下来,防止后面删除时被破坏",
" s.erase(it); // 删除整个区间",
" s.insert({l, x - 1, v}); //[l,x-1]拆分",
" // insert函数返回pair其中的first是新插入结点的迭代器",
" return s.insert({x, r, v}).first; //[x,r]拆分",
"}",
"",
"// 区间加",
"void add(int l, int r, int v) {",
" // 必须先计算itr,后计算itl",
" auto R = split(r + 1), L = split(l);",
" for (auto it = L; it != R; it++) it->v += v;",
"}",
"// 区间赋值",
"void assign(int l, int r, int v) {",
" auto R = split(r + 1), L = split(l);",
" s.erase(L, R); // 删除旧区间",
" s.insert({l, r, v}); // 增加新区间",
"}",
"",
"// 排名第x位的数值",
"int rnk(int l, int r, int x) {",
" vector<PII> v;",
" auto R = split(r + 1), L = split(l);",
" for (auto it = L; it != R; it++)",
" v.push_back({it->v, it->r - it->l + 1}); // 值,个数",
" sort(v.begin(), v.end()); // 默认按PII的第一维也就是值由小到大排序",
"",
" // 暴力拼接出排名第x大数的数值是多少",
" for (auto c : v)",
" if (c.second < x)",
" x -= c.second;",
" else",
" return c.first;",
"}",
"",
"// 快速幂 (x^y)%p",
"// #define int long long",
"int qmi(int x, int y, int p) {",
" int res = 1;",
" x %= p;",
" while (y) {",
" if (y & 1) res = res * x % p;",
" y >>= 1;",
" x = x * x % p;",
" }",
" return res;",
"}",
"",
"//[l,r]之间每个值的x次方求和对y取模",
"int calc(int l, int r, int x, int y) {",
" auto R = split(r + 1), L = split(l);",
" int res = 0;",
" for (auto it = L; it != R; it++)",
" // it枚举的是每个区间段每个区间段内的值是一样的it->v",
" // 区间段的长度 = it->r - it->l + 1",
" // 总和 = SUM(区间段的值 * 区间段的长度)",
" // 注意一步一取模",
" res = (res + qmi(it->v, x, y) * (it->r - it->l + 1) % y) % y;",
" return res;",
"}"
]
},
"线段树宏": {
"prefix": "xds_head",
"body": [
"#define ls (u << 1)",
"#define rs (u << 1 | 1)",
"#define mid ((l + r) >> 1)"
]
},
"RMQ":{"prefix":"rmq","body": [
"const int N = 200010, M = 18;",
"int w[N];",
"int f[N][M];",
"// 预处理",
"void rmq() {",
" for (int j = 0; j < M; j++) // 注意是j在外层,类似于区间DP,长度在外层",
" for (int i = 1; i + (1 << j) - 1 <= n; i++) // i(行)在内层",
" if (j == 0) // base case 边界值",
" f[i][j] = w[i];",
" else",
" f[i][j] = max(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);",
"}",
"",
"// 查询区间最大值",
"int query(int l, int r) {",
" int len = r - l + 1;",
" int k = log2(len);",
" return max(f[l][k], f[r - (1 << k) + 1][k]);",
"}"]}
}