Skip to content

Commit 87f50e5

Browse files
committed
update cpp template documentation
1 parent 7308e2d commit 87f50e5

File tree

1 file changed

+113
-108
lines changed

1 file changed

+113
-108
lines changed

docs/algorithm/cpp_templete.md

Lines changed: 113 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,144 +1301,146 @@ FixNamespaceComments: false
13011301
],
13021302
"description": "Treap文艺平衡树"
13031303
},
1304-
"Trie树": {
1304+
"字典树": {
13051305
"prefix": "tptrie",
13061306
"body": [
1307-
"struct Trie",
1307+
"template <int m, auto get_id>",
1308+
"class Trie",
13081309
"{",
1309-
" struct Node",
1310-
" {",
1311-
" unordered_map<char, Node *> ne;",
1312-
" bool end;",
1310+
"public:",
1311+
" explicit Trie(int n) : ne(n, array<int, m>{}) {}",
13131312
"",
1314-
" Node *at_or_new(char ch)",
1315-
" {",
1316-
" auto it = ne.find(ch);",
1317-
" if (it == ne.end())",
1318-
" it = ne.insert({ch, new Node()}).first;",
1319-
" return it->second;",
1320-
" }",
1313+
" int insert(const string &s) { return insert_path(s).back(); }",
13211314
"",
1322-
" Node *at(char ch) const",
1315+
" vector<int> insert_path(const string &s)",
1316+
" {",
1317+
" int p = 0;",
1318+
" vector<int> path;",
1319+
" path.reserve(s.size());",
1320+
" for (auto ch : s)",
13231321
" {",
1324-
" auto it = ne.find(ch);",
1325-
" return it == ne.end() ? nullptr : it->second;",
1322+
" p = at_or_new(p, ch);",
1323+
" path.push_back(p);",
13261324
" }",
1327-
" };",
1325+
" return path;",
1326+
" }",
13281327
"",
1329-
" Node *root = new Node();",
1328+
" int find(const string &s) const { return find_path(s).back(); }",
13301329
"",
1331-
" void insert(const string &s)",
1330+
" vector<int> find_path(const string &s) const",
13321331
" {",
1333-
" Node *p = root;",
1334-
" for(auto ch : s)",
1335-
" p = p->at_or_new(ch);",
1336-
" p->end = true;",
1332+
" int p = 0;",
1333+
" vector<int> path;",
1334+
" path.reserve(s.size());",
1335+
" for (auto ch : s)",
1336+
" {",
1337+
" p = at(p, ch);",
1338+
" path.push_back(p);",
1339+
" if (!p)",
1340+
" break;",
1341+
" }",
1342+
" return path;",
13371343
" }",
13381344
"",
1339-
" string search(const string &s)",
1340-
" {",
1341-
" Node *p = root;",
1342-
" for(auto ch : s)",
1343-
" {",
1344-
" p = p->at(ch);",
1345+
"private:",
1346+
" vector<array<int, m>> ne;",
1347+
" int idx = 1;",
13451348
"",
1346-
" }",
1349+
" int at_or_new(int p, char ch)",
1350+
" {",
1351+
" int &q = ne[p][get_id(ch)];",
1352+
" if (q == 0)",
1353+
" q = idx++;",
1354+
" return q;",
13471355
" }",
1356+
"",
1357+
" int at(int p, char ch) const { return ne[p][get_id(ch)]; }",
13481358
"};"
13491359
],
1350-
"description": "Trie树"
1360+
"description": "字典树"
13511361
},
13521362
"AC自动机": {
13531363
"prefix": "tpac",
13541364
"body": [
1355-
"struct AC",
1365+
"template <int m, auto get_id>",
1366+
"class AC",
13561367
"{",
1357-
" struct Node",
1358-
" {",
1359-
" unordered_map<char, Node *> ne;",
1360-
" vector<Node *> edge;",
1361-
" Node *fail;",
1362-
" vector<int *> pattern_ans;",
1363-
" int cnt = 0;",
1364-
"",
1365-
" Node *at_or_new(char ch)",
1366-
" {",
1367-
" auto it = ne.find(ch);",
1368-
" if (it == ne.end())",
1369-
" it = ne.insert({ch, new Node()}).first;",
1370-
" return it->second;",
1371-
" }",
1372-
"",
1373-
" Node *at(char ch)",
1374-
" {",
1375-
" auto it = ne.find(ch);",
1376-
" if (it == ne.end())",
1377-
" it = ne.insert({ch, fail->at(ch)}).first;",
1378-
" return it->second;",
1379-
" }",
1380-
" };",
1381-
"",
1382-
" Node *root = new Node();",
1368+
"public:",
1369+
" explicit AC(int n_) : n(n_), ne(n_, array<int, m>{}) {}",
13831370
"",
1384-
" void insert(int *ans_ptr, const string &s)",
1385-
" {",
1386-
" Node *p = root;",
1387-
" for (auto ch : s)",
1388-
" p = p->at_or_new(ch);",
1389-
" p->pattern_ans.push_back(ans_ptr);",
1390-
" }",
1371+
" int insert(const string &s) { return insert_path(s).back(); }",
13911372
"",
1392-
" void search(const string &s)",
1373+
" vector<int> insert_path(const string &s)",
13931374
" {",
1394-
" Node *now = root;",
1375+
" int p = 0;",
1376+
" vector<int> path;",
1377+
" path.reserve(s.size());",
13951378
" for (auto ch : s)",
13961379
" {",
1397-
" now = now->at(ch);",
1398-
" now->cnt++;",
1380+
" p = at_or_new(p, ch);",
1381+
" path.push_back(p);",
13991382
" }",
1400-
"",
1401-
" auto dfs = [&](auto &self, Node *u) -> int",
1402-
" {",
1403-
" for (auto v : u->edge)",
1404-
" u->cnt += self(self, v);",
1405-
" for (auto p : u->pattern_ans)",
1406-
" *p += u->cnt;",
1407-
" return u->cnt;",
1408-
" };",
1409-
"",
1410-
" dfs(dfs, root);",
1383+
" return path;",
14111384
" }",
14121385
"",
1413-
" void build()",
1386+
" vector<vector<int>> build()",
14141387
" {",
1415-
" queue<Node *> q;",
1416-
" for (char ch = 'a'; ch <= 'z'; ch++)",
1417-
" {",
1418-
" auto it = root->ne.find(ch);",
1419-
" if (it != root->ne.end())",
1388+
" vector<vector<int>> edge(n);",
1389+
" vector<int> fail(n);",
1390+
" queue<int> q;",
1391+
" for (auto v : ne[0])",
1392+
" if (v)",
14201393
" {",
1421-
" q.push(it->second);",
1422-
" it->second->fail = root;",
1423-
" root->edge.push_back(it->second);",
1394+
" q.push(v);",
1395+
" edge[0].push_back(v);",
14241396
" }",
1425-
" else",
1426-
" root->ne[ch] = root;",
1427-
" }",
14281397
" while (!q.empty())",
14291398
" {",
1430-
" Node *u = q.front();",
1399+
" int u = q.front();",
1400+
" int f = fail[u];",
14311401
" q.pop();",
1432-
" Node *f = u->fail;",
1433-
" for (auto [ch, v] : u->ne)",
1402+
" for (int i = 0; i < m; i++)",
14341403
" {",
1435-
" Node *f_ch = f->at(ch);",
1436-
" v->fail = f_ch;",
1437-
" f_ch->edge.push_back(v);",
1438-
" q.push(v);",
1404+
" int &v = ne[u][i];",
1405+
" if (v)",
1406+
" {",
1407+
" fail[v] = ne[f][i];",
1408+
" q.push(v);",
1409+
" edge[fail[v]].push_back(v);",
1410+
" }",
1411+
" else",
1412+
" v = ne[f][i];",
14391413
" }",
14401414
" }",
1415+
" return edge;",
1416+
" }",
1417+
"",
1418+
" vector<int> get_path(const string &s) const",
1419+
" {",
1420+
" int p = 0;",
1421+
" vector<int> path;",
1422+
" path.reserve(s.size());",
1423+
" for (auto ch : s)",
1424+
" {",
1425+
" p = at(p, ch);",
1426+
" path.push_back(p);",
1427+
" }",
1428+
" return path;",
14411429
" }",
1430+
"",
1431+
"private:",
1432+
" int n, idx = 1;",
1433+
" vector<array<int, m>> ne;",
1434+
"",
1435+
" int at_or_new(int p, char ch)",
1436+
" {",
1437+
" int &q = ne[p][get_id(ch)];",
1438+
" if (q == 0)",
1439+
" q = idx++;",
1440+
" return q;",
1441+
" }",
1442+
"",
1443+
" int at(int p, char ch) const { return ne[p][get_id(ch)]; }",
14421444
"};"
14431445
],
14441446
"description": "AC自动机"
@@ -1531,29 +1533,32 @@ FixNamespaceComments: false
15311533
"description": "Dijkstra最短路"
15321534
},
15331535
"网络最大流": {
1534-
"prefix": "tpdinic",
1536+
"prefix": "tpdininc",
15351537
"body": [
1538+
"template <class Cap>",
15361539
"struct Network",
15371540
"{",
15381541
" struct Edge",
15391542
" {",
1540-
" int to, flow, rev_idx;",
1543+
" int to;",
1544+
" Cap flow;",
1545+
" int rev_idx;",
15411546
" };",
15421547
"",
15431548
" int n;",
15441549
" vector<vector<Edge>> edge;",
15451550
"",
15461551
" Network(int n) : n(n), edge(n) {}",
15471552
"",
1548-
" void add_edge(int u, int v, int w)",
1553+
" void add_edge(int u, int v, Cap w)",
15491554
" {",
15501555
" int ui = edge[u].size();",
15511556
" int vi = edge[v].size();",
15521557
" edge[u].push_back({v, w, vi});",
15531558
" edge[v].push_back({u, 0, ui});",
15541559
" }",
15551560
"",
1556-
" int dinic(int s, int t)",
1561+
" Cap dinic(int s, int t)",
15571562
" {",
15581563
" vector<int> dep(n);",
15591564
" vector<size_t> cur(n);",
@@ -1583,19 +1588,19 @@ FixNamespaceComments: false
15831588
" return dep[t] != -1;",
15841589
" };",
15851590
"",
1586-
" auto dfs = [&](auto &self, int u, int in) -> int",
1591+
" auto dfs = [&](auto &self, int u, Cap in) -> Cap",
15871592
" {",
15881593
" if (u == t)",
15891594
" return in;",
1590-
" int out = 0;",
1595+
" Cap out = 0;",
15911596
" for (size_t &i = cur[u]; i < edge[u].size(); i++)",
15921597
" {",
15931598
" Edge &e = edge[u][i];",
15941599
" int v = e.to;",
15951600
" if (dep[v] == dep[u] + 1 && e.flow)",
15961601
" {",
15971602
" Edge &r = edge[v][e.rev_idx];",
1598-
" int res = self(self, v, min(in, e.flow));",
1603+
" Cap res = self(self, v, min(in, e.flow));",
15991604
" e.flow -= res;",
16001605
" r.flow += res;",
16011606
" in -= res;",
@@ -1607,9 +1612,9 @@ FixNamespaceComments: false
16071612
" return out;",
16081613
" };",
16091614
"",
1610-
" int ans = 0;",
1615+
" Cap ans = 0;",
16111616
" while (bfs())",
1612-
" ans += dfs(dfs, s, numeric_limits<int>::max());",
1617+
" ans += dfs(dfs, s, numeric_limits<Cap>::max());",
16131618
" return ans;",
16141619
" }",
16151620
"};"

0 commit comments

Comments
 (0)