{ "C++模板初始化": { "prefix": "cpp", "body": [ "#include ", "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 ", "", "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", "", "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 ", "", "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 ", "", "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 ", "", "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 ", "", "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 ", "", "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 ", "", "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 PII;", "#define x first", "#define y second", ] }, "整数数对PII": { "description": "整数数对PII", "prefix": "pii", "body": [ "typedef pair PII;", ] }, "双级数对": { "prefix": "piii", "body": [ "#define x first", "#define y second", "typedef pair> PIII;", ], "description": "双级数对" }, "无穷大": { "prefix": "inf", "body": [ "const int INF = 0x3f3f3f3f;", ], "description": "无穷大" }, "万能头文件": { "prefix": "stdc", "body": [ "#include ", ], "description": "万能头文件" }, "Dijkstra算法": { "prefix": "dijkstra", "body": [ "const int N = 10010, M = N * 2;", "typedef pair 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, greater> 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 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 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 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 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 MSI;" ] }, "MSP": { "prefix": "msp", "body": [ "typedef unordered_map> 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 ", "#include ", "#include ", "#include ", "#include ", "#include ", "#include ", "#include " ] }, "离散化": { "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 s; // 柯朵莉树的区间集合", "", "// 分裂:[l,x-1],[x,r]", "set::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 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]);", "}"]} }