|
1 | | -## 使用教程 |
| 1 | +## 设置 |
2 | 2 |
|
| 3 | +```json |
| 4 | +{ |
| 5 | + // 删除文件不确认 |
| 6 | + "explorer.confirmDelete": false, |
| 7 | + // 移动文件不确认 |
| 8 | + "explorer.confirmDragAndDrop": false, |
| 9 | + // 添加希望被忽略的文件,这样一些文件虽然存在于当前工作目录下,但是不会被显示在左侧的文件浏览器里 |
| 10 | + "files.exclude": { |
| 11 | + // dSYM 文件具有调试信息,普通使用的话不看到它就可以了 |
| 12 | + "**/*.exe": true, |
| 13 | + "**/*.out": true, |
| 14 | + ".cph": true, |
| 15 | + ".clang-format": true, |
| 16 | + }, |
| 17 | + // 启用 code-runner 快捷键 |
| 18 | + "workspaceKeybindings.code-runner.enable": true, |
| 19 | + // -------------------------------------------------------------------------------------- |
| 20 | + // Code Runner |
| 21 | + // To run code: |
| 22 | + // use shortcut "Ctrl Opt N" * |
| 23 | + // or press F1 and then select/type Run Code, |
| 24 | + // or right click the Text Editor and then click Run Code in editor context menu |
| 25 | + // or click Run Code button in editor title menu |
| 26 | + // or click Run Code button in context menu of file explorer |
| 27 | + // To stop the running code: |
| 28 | + // use shortcut "Ctrl Opt M" * |
| 29 | + // or press F1 and then select/type Stop Code Run |
| 30 | + // or right click the Output Channel and then click Stop Code Run in context menu |
| 31 | + "code-runner.executorMap": { |
| 32 | + // Introduction: |
| 33 | + // Make sure the executor PATH of each language is set in the environment variable. |
| 34 | + // You could also add entry into "code-runner.executorMap" to set the executor PATH. |
| 35 | + // Supported customized parameters: |
| 36 | + // $workspaceRoot: The path of the folder opened in VS Code |
| 37 | + // $dir: The directory of the code file being run |
| 38 | + // $fullFileName: The full name of the code file being run |
| 39 | + // $fileName: The base name of the code file being run, that is the file without the directory |
| 40 | + // $fileNameWithoutExt: The base name of the code file being run without its extension |
| 41 | + /* ------ 编译、运行只有一个文件的cpp文件 ------ */ |
| 42 | + // 注:路径中有空格不会出现问题 |
| 43 | + "cpp": "clang++ $fullFileName -o $dir\"$fileNameWithoutExt\"\".out\" -W -Wall -O2 -std=c++17 -I$workspaceRoot/lib && $dir\"$fileNameWithoutExt\"\".out\"", |
| 44 | + // 其中 $fullFileName 是绝对路径,是主文件 |
| 45 | + // 自己决定是否加入 && rm $dir\"$fileNameWithoutExt\"\".out\"(也可以添加"files.exclude") |
| 46 | + /* ------ 编译、运行多个cpp文件 ------ */ |
| 47 | + // "cpp": "g++ $fullFileName <file_to_link> -o $dir\"$fileNameWithoutExt\"\".out\" -W -Wall -O2 -std=c++17 && $dir\"$fileNameWithoutExt\"\".out\"", |
| 48 | + // <file_to_link>的写法: |
| 49 | + // 一般的,你也可以直接写绝对路径 |
| 50 | + // \"/path/xxxx.cpp\" |
| 51 | + // 如果你链接的cpp文件和主文件在一个目录下: |
| 52 | + // $dir\"xxxx.cpp\" |
| 53 | + // 更一般的,如果你链接的cpp文件不和主文件在一个目录下,需要从当前VSCode的工作目录补充相对路径从而形成绝对路径: |
| 54 | + // $workspaceRoot\"relative/path/xxxx.cpp\" |
| 55 | + /* ------ 编译c文件 ------ */ |
| 56 | + "c": "clang $fullFileName -o $dir\"$fileNameWithoutExt\"\".out\" -W -Wall -O2 -std=gnu11 && $dir\"$fileNameWithoutExt\"\".out\"", |
| 57 | + // "c": "gcc $fullFileName <file_to_link> -o $dir\"$fileNameWithoutExt\"\".out\" -W -Wall -O2 -std=c17 && $dir\"$fileNameWithoutExt\"\".out\"", |
| 58 | + }, |
| 59 | + // Whether to clear previous output before each run (default is false): |
| 60 | + "code-runner.clearPreviousOutput": true, |
| 61 | + // Whether to save all files before running (default is false): |
| 62 | + "code-runner.saveAllFilesBeforeRun": false, |
| 63 | + // Whether to save the current file before running (default is false): |
| 64 | + "code-runner.saveFileBeforeRun": true, |
| 65 | + // Whether to show extra execution message like [Running] ... and [Done] ... (default is true): |
| 66 | + "code-runner.showExecutionMessage": true, // cannot see that message is you set "code-runner.runInTerminal" to true |
| 67 | + // Whether to run code in Integrated Terminal (only support to run whole file in Integrated Terminal, neither untitled file nor code snippet) (default is false): |
| 68 | + "code-runner.runInTerminal": true, // cannot input data when setting to false |
| 69 | + // Whether to preserve focus on code editor after code run is triggered (default is true, the code editor will keep focus; when it is false, Terminal or Output Channel will take focus): |
| 70 | + "code-runner.preserveFocus": false, |
| 71 | + // Whether to ignore selection to always run entire file. (Default is false) |
| 72 | + "code-runner.ignoreSelection": true, |
| 73 | + // 本地 clangd 路径 |
| 74 | + // "clangd.path": "/usr/bin/clangd", |
| 75 | + "clangd.arguments": [ |
| 76 | + // "--header-insertion=never", // 是否重复插入头文件,用万能头的话设置成never |
| 77 | + "--query-driver=/usr/bin/clang++", // 将编译的所有工具链都添加进 LSP |
| 78 | + "--log=verbose" |
| 79 | + ], |
| 80 | + // 没有找到 compile_commands.json 时默认的编译器参数是什么 |
| 81 | + "clangd.fallbackFlags": [ |
| 82 | + "-W", |
| 83 | + "-Wall", |
| 84 | + "-O2", |
| 85 | + "-std=c++17", |
| 86 | + "-I/root/cpp/lib", |
| 87 | + ], |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +## 算法模板 |
| 92 | + |
| 93 | +使用教程: |
3 | 94 | - 在 VSCode 工作区的 `.vscode` 文件夹下创建 `XXX.code-snippets` 文件,其中 `XXX` 表示工作区的名字,例如 `cpp` 工作区,就创建 `cpp.code-snippets`。 |
4 | 95 | - 复制下列内容,粘贴进去。 |
5 | 96 | - 使用 `prefix` 字段的快捷键就可以呼出代码模板,例如 `tpdsu` 就可以输出并查集模板。 |
|
60 | 151 | "public:", |
61 | 152 | " explicit DSU(int n) : parent_or_size(n, -1) {}", |
62 | 153 | "", |
63 | | - " void merge(int a, int b)", |
| 154 | + " int merge(int a, int b)", |
| 155 | + " {", |
| 156 | + " int x = leader(a), y = leader(b);", |
| 157 | + " if (x == y)", |
| 158 | + " return x;", |
| 159 | + " if (-parent_or_size[x] < -parent_or_size[y])", |
| 160 | + " swap(x, y);", |
| 161 | + " parent_or_size[x] += parent_or_size[y];", |
| 162 | + " parent_or_size[y] = x;", |
| 163 | + " return x;", |
| 164 | + " }", |
| 165 | + "", |
| 166 | + " int leader(int a) { return parent_or_size[a] < 0 ? a : parent_or_size[a] = leader(parent_or_size[a]); }", |
| 167 | + "", |
| 168 | + " bool same(int a, int b) { return leader(a) == leader(b); }", |
| 169 | + "", |
| 170 | + " int size(int a) { return -parent_or_size[leader(a)]; }", |
| 171 | + "", |
| 172 | + "private:", |
| 173 | + " vector<int> parent_or_size;", |
| 174 | + "};" |
| 175 | + ], |
| 176 | + "description": "并查集(按秩合并)" |
| 177 | + }, |
| 178 | + "并查集(group)": { |
| 179 | + "prefix": "tpdsu", |
| 180 | + "body": [ |
| 181 | + "class DSU", |
| 182 | + "{", |
| 183 | + "public:", |
| 184 | + " explicit DSU(int n) : parent_or_size(n, -1) {}", |
| 185 | + "", |
| 186 | + " int merge(int a, int b)", |
64 | 187 | " {", |
65 | 188 | " int x = leader(a), y = leader(b);", |
66 | 189 | " if (x == y)", |
67 | | - " return;", |
| 190 | + " return x;", |
68 | 191 | " if (-parent_or_size[x] < -parent_or_size[y])", |
69 | | - " std::swap(x, y);", |
| 192 | + " swap(x, y);", |
70 | 193 | " parent_or_size[x] += parent_or_size[y];", |
71 | 194 | " parent_or_size[y] = x;", |
| 195 | + " return x;", |
72 | 196 | " }", |
73 | 197 | "", |
74 | 198 | " int leader(int a) { return parent_or_size[a] < 0 ? a : parent_or_size[a] = leader(parent_or_size[a]); }", |
|
77 | 201 | "", |
78 | 202 | " int size(int a) { return -parent_or_size[leader(a)]; }", |
79 | 203 | "", |
| 204 | + " vector<vector<int>> group()", |
| 205 | + " {", |
| 206 | + " int n = parent_or_size.size();", |
| 207 | + " std::vector<int> leader_buf(n), group_size(n);", |
| 208 | + " for (int i = 0; i < n; i++)", |
| 209 | + " {", |
| 210 | + " leader_buf[i] = leader(i);", |
| 211 | + " group_size[leader_buf[i]]++;", |
| 212 | + " }", |
| 213 | + " std::vector<std::vector<int>> result(n);", |
| 214 | + " for (int i = 0; i < n; i++)", |
| 215 | + " result[i].reserve(group_size[i]);", |
| 216 | + " for (int i = 0; i < n; i++)", |
| 217 | + " result[leader_buf[i]].push_back(i);", |
| 218 | + " result.erase(", |
| 219 | + " std::remove_if(result.begin(), result.end(),", |
| 220 | + " [&](const std::vector<int> &v)", |
| 221 | + " { return v.empty(); }),", |
| 222 | + " result.end());", |
| 223 | + " return result;", |
| 224 | + " }", |
| 225 | + "", |
80 | 226 | "private:", |
81 | 227 | " vector<int> parent_or_size;", |
82 | 228 | "};" |
83 | 229 | ], |
84 | | - "description": "并查集(按秩合并)" |
| 230 | + "description": "并查集(支持group)" |
85 | 231 | }, |
86 | 232 | "扩展欧几里得": { |
87 | 233 | "prefix": "tpexgcd", |
|
104 | 250 | ], |
105 | 251 | "description": "扩展欧几里得" |
106 | 252 | }, |
| 253 | + "树状数组": { |
| 254 | + "prefix": "tpfenwick", |
| 255 | + "body": [ |
| 256 | + "template <typename T>", |
| 257 | + "class FenwickTree", |
| 258 | + "{", |
| 259 | + "public:", |
| 260 | + " FenwickTree(int n) : n(n), t(n + 1) {}", |
| 261 | + "", |
| 262 | + " void add(int x, T k)", |
| 263 | + " {", |
| 264 | + " for (; x <= n; x += lowbit(x))", |
| 265 | + " t[x] += k;", |
| 266 | + " }", |
| 267 | + "", |
| 268 | + " int lower_bound(T k) const", |
| 269 | + " {", |
| 270 | + " int x = 0;", |
| 271 | + " T sum = 0;", |
| 272 | + " for (int i = 1 << __lg(n); i; i >>= 1)", |
| 273 | + " {", |
| 274 | + " if (x + i > n || sum + t[x + i] >= k)", |
| 275 | + " continue;", |
| 276 | + " x += i;", |
| 277 | + " sum += t[x];", |
| 278 | + " }", |
| 279 | + " return x + 1;", |
| 280 | + " }", |
| 281 | + "", |
| 282 | + "private:", |
| 283 | + " int n;", |
| 284 | + " vector<T> t;", |
| 285 | + "", |
| 286 | + " int lowbit(int x) const { return x & -x; }", |
| 287 | + "};" |
| 288 | + ], |
| 289 | + "description": "树状数组" |
| 290 | + }, |
107 | 291 | "TreapSet普通平衡树": { |
108 | 292 | "prefix": "tptreap", |
109 | 293 | "body": [ |
|
666 | 850 | "Dijkstra最短路": { |
667 | 851 | "prefix": "tpdijkstra", |
668 | 852 | "body": [ |
| 853 | + "template <typename T>", |
669 | 854 | "struct Graph", |
670 | 855 | "{", |
671 | 856 | " struct Edge", |
|
676 | 861 | " int n;", |
677 | 862 | " vector<vector<Edge>> edge;", |
678 | 863 | "", |
679 | | - " Graph(int n) : n(n), edge(n + 1) {}", |
| 864 | + " Graph(int n) : n(n), edge(n) {}", |
680 | 865 | "", |
681 | 866 | " void add_edge(int u, int v, int w) { edge[u].push_back({v, w}); }", |
682 | 867 | "", |
683 | | - " vector<int> dijkstra(int s) const", |
| 868 | + " vector<T> dijkstra(int s) const", |
684 | 869 | " {", |
685 | 870 | " struct Node", |
686 | 871 | " {", |
687 | | - " int u, d;", |
| 872 | + " int u;", |
| 873 | + " T d;", |
688 | 874 | " bool operator>(const Node &other) const { return d > other.d; }", |
689 | 875 | " };", |
690 | 876 | "", |
691 | | - " vector<int> dis(n + 1, numeric_limits<int>::max());", |
| 877 | + " vector<T> dis(n, numeric_limits<T>::max());", |
692 | 878 | " dis[s] = 0;", |
693 | 879 | " priority_queue<Node, vector<Node>, greater<Node>> heap;", |
694 | 880 | " heap.push({s, 0});", |
|
726 | 912 | " int n;", |
727 | 913 | " vector<vector<Edge>> edge;", |
728 | 914 | "", |
729 | | - " Network(int n) : n(n), edge(n + 1) {}", |
| 915 | + " Network(int n) : n(n), edge(n) {}", |
730 | 916 | "", |
731 | 917 | " void add_edge(int u, int v, int w)", |
732 | 918 | " {", |
|
738 | 924 | "", |
739 | 925 | " int dinic(int s, int t)", |
740 | 926 | " {", |
741 | | - " vector<int> dep(n + 1);", |
742 | | - " vector<size_t> cur(n + 1);", |
| 927 | + " vector<int> dep(n);", |
| 928 | + " vector<size_t> cur(n);", |
743 | 929 | "", |
744 | 930 | " auto bfs = [&]() -> bool", |
745 | 931 | " {", |
746 | | - " dep.assign(n + 1, -1);", |
747 | | - " cur.assign(n + 1, 0);", |
| 932 | + " dep.assign(n, -1);", |
| 933 | + " cur.assign(n, 0);", |
748 | 934 | " dep[s] = 0;", |
749 | 935 | " queue<int> q;", |
750 | 936 | " q.push(s);", |
|
924 | 1110 | "};" |
925 | 1111 | ], |
926 | 1112 | "description": "莫队查询排序" |
927 | | - } |
| 1113 | + }, |
| 1114 | + "布尔矩阵": { |
| 1115 | + "prefix": "tpmatrix", |
| 1116 | + "body": [ |
| 1117 | + "const int N = $0;", |
| 1118 | + "using RowVec = bitset<N>;", |
| 1119 | + "", |
| 1120 | + "class Matrix", |
| 1121 | + "{", |
| 1122 | + "public:", |
| 1123 | + " RowVec &operator[](int i) { return a[i]; }", |
| 1124 | + " const RowVec &operator[](int i) const { return a[i]; }", |
| 1125 | + "", |
| 1126 | + " Matrix operator*(const Matrix &y) const;", |
| 1127 | + "", |
| 1128 | + "private:", |
| 1129 | + " array<RowVec, N> a;", |
| 1130 | + "};", |
| 1131 | + "", |
| 1132 | + "RowVec operator*(const RowVec &v, const Matrix &m)", |
| 1133 | + "{", |
| 1134 | + " RowVec res;", |
| 1135 | + " for (int j = 0; j < N; j++)", |
| 1136 | + " if (v[j])", |
| 1137 | + " res |= m[j];", |
| 1138 | + " return res;", |
| 1139 | + "}", |
| 1140 | + "", |
| 1141 | + "Matrix Matrix::operator*(const Matrix &y) const", |
| 1142 | + "{", |
| 1143 | + " Matrix res;", |
| 1144 | + " for (int i = 0; i < N; i++)", |
| 1145 | + " res[i] = a[i] * y;", |
| 1146 | + " return res;", |
| 1147 | + "}", |
| 1148 | + "", |
| 1149 | + "Matrix qpow(Matrix a, LL b)", |
| 1150 | + "{", |
| 1151 | + " Matrix res;", |
| 1152 | + " for (int i = 0; i < N; i++)", |
| 1153 | + " res[i][i] = 1;", |
| 1154 | + " while (b)", |
| 1155 | + " {", |
| 1156 | + " if (b & 1)", |
| 1157 | + " res = res * a;", |
| 1158 | + " b >>= 1;", |
| 1159 | + " a = a * a;", |
| 1160 | + " }", |
| 1161 | + " return res;", |
| 1162 | + "}" |
| 1163 | + ], |
| 1164 | + "description": "布尔矩阵" |
| 1165 | + }, |
| 1166 | + "manacher算法": { |
| 1167 | + "prefix": "tpmanacher", |
| 1168 | + "body": [ |
| 1169 | + "int manacher(const string &s, char ch)", |
| 1170 | + "{", |
| 1171 | + " int n = s.size();", |
| 1172 | + " int m = 2 * n + 1;", |
| 1173 | + " string t(m, ch);", |
| 1174 | + " for (int i = 0, j = 1; i < n; i++, j += 2)", |
| 1175 | + " t[j] = s[i];", |
| 1176 | + " vector<int> d(m);", |
| 1177 | + " int ans = 0;", |
| 1178 | + " for(int i = 0, l = 0, r = -1; i < m; i++)", |
| 1179 | + " {", |
| 1180 | + " int k = i > r ? 1 : min(d[l+r-i], r-i+1);", |
| 1181 | + " while(i-k >= 0 && i + k < m && t[i-k] == t[i+k])", |
| 1182 | + " k++;", |
| 1183 | + " d[i] = k;", |
| 1184 | + " ans = max(ans, 2 * k - 1);", |
| 1185 | + " if(i + k - 1 > r)", |
| 1186 | + " {", |
| 1187 | + " r = i + k - 1;", |
| 1188 | + " l = i - k + 1;", |
| 1189 | + " }", |
| 1190 | + " }", |
| 1191 | + " return ans / 2;", |
| 1192 | + "}" |
| 1193 | + ], |
| 1194 | + "description": "manacher算法" |
| 1195 | + }, |
928 | 1196 | } |
929 | 1197 | ``` |
930 | 1198 |
|
0 commit comments