luogu4407 [JSOI2009]電子字典 字串hash + hash表
阿新 • • 發佈:2018-11-27
暴力列舉,然後\(hash\)表判斷
複雜度\(O(26 * 20 * n)\)
具體而言
對於操作1:暴力列舉刪除
對於操作2:暴力新增,注意新增不要重複
對於操作3:暴力替換,同樣的注意不要重複
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define ri register int #define ull unsigned long long #define rep(io, st, ed) for(ri io = st; io <= ed; io ++) #define drep(io, ed, st) for(ri io = ed; io >= st; io --) const int yume = 19260817; const int sid = 4300050; char s[50]; int n, m, L, cnp; ull num, pre[50], wei[50]; int cap[sid], nxt[sid], val[sid]; ull fz[sid]; inline int get(ull v) { int k = v & 4194303; for(int i = cap[k]; i; i = nxt[i]) if(fz[i] == v) return i; return 0; } inline void ins(ull v) { int k = v & 4194303; int p = get(v); if(!p) { nxt[++ cnp] = cap[k]; fz[cnp] = v; cap[k] = cnp; val[cnp] = 1; } else val[p] ++; } inline ull v(int l, int r) { if(l > r) return 0; return pre[r] - pre[l - 1] * wei[r - l + 1]; } inline ull calc1(int p) { return v(1, p - 1) * wei[L - p] + v(p + 1, L); } inline ull calc2(int p, char c) { return v(1, p - 1) * wei[L - p + 1] + v(p + 1, L) + c * wei[L - p]; } inline ull calc3(int p, char c) { return v(1, p) * wei[L - p + 1] + v(p + 1, L) + c * wei[L - p]; } int main() { wei[0] = 1; rep(i, 1, 30) wei[i] = wei[i - 1] * yume; cin >> n >> m; rep(i, 1, n) { scanf("%s", s + 1); L = strlen(s + 1); num = 0; rep(j, 1, L) num = num * yume + s[j]; ins(num); } rep(i, 1, m) { scanf("%s", s + 1); L = strlen(s + 1); rep(j, 1, L) pre[j] = pre[j - 1] * yume + s[j]; if(get(pre[L])) { printf("-1\n"); continue; } int ans = 0; rep(j, 1, L) if(s[j] != s[j - 1]) ans += val[get(calc1(j))]; rep(j, 1, L) rep(c, 'a', 'z') if(c != s[j]) ans += val[get(calc2(j, c))]; rep(j, 0, L) rep(c, 'a', 'z') if(c != s[j + 1]) ans += val[get(calc3(j, c))]; printf("%d\n", ans); } return 0; }