1 条题解
-
0
手写哈希表
vector 写法
#include <bits/stdc++.h> using namespace std; const int MOD = 998244353; int n, m; int len[212345]; int nxt[212345]; int pre[212345]; const int SZ = 3123456; struct hash_map { // 哈希表模板 vector<pair<unsigned long long, int>> data[SZ]; int hash(unsigned long long u) { return u % SZ; } int &operator[](unsigned long long u) { int hu = hash(u); // 获取头指针 for (int i = 0; i < data[hu].size(); i++) if (data[hu][i].first == u) return data[hu][i].second; data[hu].push_back({u, 0}); return data[hu].back().second; } } hm; unsigned long long B[105]; int now[105]; unsigned long long nowH[105]; unsigned long long sH[10000005]; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n >> m; B[0] = 1; for (int i = 1; i <= 100; i++) B[i] = B[i - 1] * 137; for (int i = 1; i <= n; i++) { cin >> len[i]; nxt[i] = pre[i] = -1; hm[len[i]]++; } for (int T = 1; T <= m; T++) { int op, x, y, k; string S; cin >> op; if (op == 1) { cin >> x >> y; // 合并 for (int i = 1; i <= 100; i++) now[i] = nowH[i] = 0; for (int i = x, cnt = 50; i != -1 && cnt >= 1; i = pre[i], cnt--) now[cnt] = len[i]; for (int i = y, cnt = 51; i != -1 && cnt <= 100; i = nxt[i], cnt++) now[cnt] = len[i]; for (int i = 1; i <= 100; i++) nowH[i] = nowH[i - 1] * 137 + now[i]; for (int i = 1; i <= 50; i++) if (now[i] != 0) for (int j = 51; j <= i + 50 - 1; j++) if (now[j] != 0) { unsigned long long h = nowH[j] - nowH[i - 1] * B[j - i + 1]; hm[h]++; } nxt[x] = y; pre[y] = x; } else if (op == 2) { cin >> x; y = nxt[x]; // 分裂 pre[y] = -1; nxt[x] = -1; for (int i = 1; i <= 100; i++) now[i] = nowH[i] = 0; for (int i = x, cnt = 50; i != -1 && cnt >= 1; i = pre[i], cnt--) now[cnt] = len[i]; for (int i = y, cnt = 51; i != -1 && cnt <= 100; i = nxt[i], cnt++) now[cnt] = len[i]; for (int i = 1; i <= 100; i++) nowH[i] = nowH[i - 1] * 137 + now[i]; for (int i = 1; i <= 50; i++) if (now[i] != 0) for (int j = 51; j <= i + 50 - 1; j++) if (now[j] != 0) { unsigned long long h = nowH[j] - nowH[i - 1] * B[j - i + 1]; hm[h]--; } } else if (op == 3) { cin >> S >> k; for (int i = 1; i <= S.length(); i++) sH[i] = sH[i - 1] * 137 + S[i - 1] - '0'; // mul(f(t)) int ans = 1; bool flag = false; for (int i = 1; i + k - 1 <= S.length(); i++) { unsigned long long h = sH[i + k - 1] - sH[i - 1] * B[k]; int cnt = hm[h]; ans = (long long)ans * cnt % MOD; flag = true; } cout << ans << "\n"; } } return 0; }
链式前向星写法
#include <bits/stdc++.h> using namespace std; const int MOD = 998244353; int n, m; int len[212345]; int nxt[212345]; int pre[212345]; const int SZ = 3123456; struct hash_map { // 哈希表模板 struct data { unsigned long long u; int v, nex; }; // 前向星结构 data e[SZ << 1]; // SZ 是 const int 表示大小 int h[SZ], cnt; int hash(unsigned long long u) { return u % SZ; } int &operator[](unsigned long long u) { int hu = hash(u); // 获取头指针 for (int i = h[hu]; i; i = e[i].nex) if (e[i].u == u) return e[i].v; return e[++cnt] = (data){u, 0, h[hu]}, h[hu] = cnt, e[cnt].v; } hash_map() { cnt = 0; memset(h, 0, sizeof(h)); } } hm; unsigned long long B[105]; int now[105]; unsigned long long nowH[105]; unsigned long long sH[10000005]; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n >> m; B[0] = 1; for (int i = 1; i <= 100; i++) B[i] = B[i - 1] * 137; for (int i = 1; i <= n; i++) { cin >> len[i]; nxt[i] = pre[i] = -1; hm[len[i]]++; } for (int T = 1; T <= m; T++) { int op, x, y, k; string S; cin >> op; if (op == 1) { cin >> x >> y; //合并 for (int i = 1; i <= 100; i++) now[i] = nowH[i] = 0; for (int i = x, cnt = 50; i != -1 && cnt >= 1; i = pre[i], cnt--) now[cnt] = len[i]; for (int i = y, cnt = 51; i != -1 && cnt <= 100; i = nxt[i], cnt++) now[cnt] = len[i]; for (int i = 1; i <= 100; i++) nowH[i] = nowH[i - 1] * 137 + now[i]; for (int i = 1; i <= 50; i++) if (now[i] != 0) for (int j = 51; j <= i + 50 - 1; j++) if (now[j] != 0) { unsigned long long h = nowH[j] - nowH[i - 1] * B[j - i + 1]; hm[h]++; } nxt[x] = y; pre[y] = x; } else if (op == 2) { cin >> x; y = nxt[x]; //分裂 pre[y] = -1; nxt[x] = -1; for (int i = 1; i <= 100; i++) now[i] = nowH[i] = 0; for (int i = x, cnt = 50; i != -1 && cnt >= 1; i = pre[i], cnt--) now[cnt] = len[i]; for (int i = y, cnt = 51; i != -1 && cnt <= 100; i = nxt[i], cnt++) now[cnt] = len[i]; for (int i = 1; i <= 100; i++) nowH[i] = nowH[i - 1] * 137 + now[i]; for (int i = 1; i <= 50; i++) if (now[i] != 0) for (int j = 51; j <= i + 50 - 1; j++) if (now[j] != 0) { unsigned long long h = nowH[j] - nowH[i - 1] * B[j - i + 1]; hm[h]--; } } else if (op == 3) { cin >> S >> k; for (int i = 1; i <= S.length(); i++) sH[i] = sH[i - 1] * 137 + S[i - 1] - '0'; // mul(f(t)) int ans = 1; bool flag = false; for (int i = 1; i + k - 1 <= S.length(); i++) { unsigned long long h = sH[i + k - 1] - sH[i - 1] * B[k]; int cnt = hm[h]; ans = (long long)ans * cnt % MOD; flag = true; } cout << ans << "\n"; } } return 0; }
自带 unordered_map 的超时 92 分
#include <bits/stdc++.h> using namespace std; const int MOD = 998244353; int n, m; int len[212345]; int nxt[212345]; int pre[212345]; const int SZ = 3123456; unordered_map<unsigned long long, int> hm; unsigned long long B[105]; int now[105]; unsigned long long nowH[105]; unsigned long long sH[10000005]; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n >> m; B[0] = 1; for (int i = 1; i <= 100; i++) B[i] = B[i - 1] * 137; for (int i = 1; i <= n; i++) { cin >> len[i]; nxt[i] = pre[i] = -1; hm[len[i]]++; } for (int T = 1; T <= m; T++) { int op, x, y, k; string S; cin >> op; if (op == 1) { cin >> x >> y; // 合并 for (int i = 1; i <= 100; i++) now[i] = nowH[i] = 0; for (int i = x, cnt = 50; i != -1 && cnt >= 1; i = pre[i], cnt--) now[cnt] = len[i]; for (int i = y, cnt = 51; i != -1 && cnt <= 100; i = nxt[i], cnt++) now[cnt] = len[i]; for (int i = 1; i <= 100; i++) nowH[i] = nowH[i - 1] * 137 + now[i]; for (int i = 50; i >= 1; i--) { if (now[i] == 0) break; for (int j = 51; j <= i + 50 - 1; j++) { if (now[j] == 0) break; unsigned long long h = nowH[j] - nowH[i - 1] * B[j - i + 1]; hm[h]++; } } nxt[x] = y; pre[y] = x; } else if (op == 2) { cin >> x; y = nxt[x]; // 分裂 pre[y] = -1; nxt[x] = -1; for (int i = 1; i <= 100; i++) now[i] = nowH[i] = 0; for (int i = x, cnt = 50; i != -1 && cnt >= 1; i = pre[i], cnt--) now[cnt] = len[i]; for (int i = y, cnt = 51; i != -1 && cnt <= 100; i = nxt[i], cnt++) now[cnt] = len[i]; for (int i = 1; i <= 100; i++) nowH[i] = nowH[i - 1] * 137 + now[i]; for (int i = 50; i >= 1; i--) { if (now[i] == 0) break; for (int j = 51; j <= i + 50 - 1; j++) { if (now[j] == 0) break; unsigned long long h = nowH[j] - nowH[i - 1] * B[j - i + 1]; hm[h]--; } } } else if (op == 3) { cin >> S >> k; for (int i = 1; i <= S.length(); i++) sH[i] = sH[i - 1] * 137 + S[i - 1] - '0'; // mul(f(t)) int ans = 1; bool flag = false; for (int i = 1; i + k - 1 <= S.length(); i++) { unsigned long long h = sH[i + k - 1] - sH[i - 1] * B[k]; int cnt = hm[h]; ans = (long long)ans * cnt % MOD; flag = true; } cout << ans << "\n"; } } return 0; }
map 的超时 60 分
#include <bits/stdc++.h> using namespace std; const int MOD = 998244353; int n, m; int len[212345]; int nxt[212345]; int pre[212345]; const int SZ = 3123456; map<unsigned long long, int> hm; unsigned long long B[105]; int now[105]; unsigned long long nowH[105]; unsigned long long sH[10000005]; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n >> m; B[0] = 1; for (int i = 1; i <= 100; i++) B[i] = B[i - 1] * 137; for (int i = 1; i <= n; i++) { cin >> len[i]; nxt[i] = pre[i] = -1; hm[len[i]]++; } for (int T = 1; T <= m; T++) { int op, x, y, k; string S; cin >> op; if (op == 1) { cin >> x >> y; // 合并 for (int i = 1; i <= 100; i++) now[i] = nowH[i] = 0; for (int i = x, cnt = 50; i != -1 && cnt >= 1; i = pre[i], cnt--) now[cnt] = len[i]; for (int i = y, cnt = 51; i != -1 && cnt <= 100; i = nxt[i], cnt++) now[cnt] = len[i]; for (int i = 1; i <= 100; i++) nowH[i] = nowH[i - 1] * 137 + now[i]; for (int i = 1; i <= 50; i++) if (now[i] != 0) for (int j = 51; j <= i + 50 - 1; j++) if (now[j] != 0) { unsigned long long h = nowH[j] - nowH[i - 1] * B[j - i + 1]; hm[h]++; } nxt[x] = y; pre[y] = x; } else if (op == 2) { cin >> x; y = nxt[x]; // 分裂 pre[y] = -1; nxt[x] = -1; for (int i = 1; i <= 100; i++) now[i] = nowH[i] = 0; for (int i = x, cnt = 50; i != -1 && cnt >= 1; i = pre[i], cnt--) now[cnt] = len[i]; for (int i = y, cnt = 51; i != -1 && cnt <= 100; i = nxt[i], cnt++) now[cnt] = len[i]; for (int i = 1; i <= 100; i++) nowH[i] = nowH[i - 1] * 137 + now[i]; for (int i = 1; i <= 50; i++) if (now[i] != 0) for (int j = 51; j <= i + 50 - 1; j++) if (now[j] != 0) { unsigned long long h = nowH[j] - nowH[i - 1] * B[j - i + 1]; hm[h]--; } } else if (op == 3) { cin >> S >> k; for (int i = 1; i <= S.length(); i++) sH[i] = sH[i - 1] * 137 + S[i - 1] - '0'; // mul(f(t)) int ans = 1; bool flag = false; for (int i = 1; i + k - 1 <= S.length(); i++) { unsigned long long h = sH[i + k - 1] - sH[i - 1] * B[k]; int cnt = hm[h]; ans = (long long)ans * cnt % MOD; flag = true; } cout << ans << "\n"; } } return 0; }
- 1
信息
- ID
- 1361
- 时间
- 3000ms
- 内存
- 1250MiB
- 难度
- 6
- 标签
- 递交数
- 31
- 已通过
- 5
- 上传者