@@ -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