哈希练习笔记
常用哈希模数 : 1019260817
, 原根 : 19491001
三哈希模板:
// three mod hash ----------------------------------
const int moda = 998244353;
const int modb = 1004535809;
const int modc = 1e9 + 7;
const int G = 917120411;
int qpowa[N], qpowb[N], qpowc[N];
struct thash { int vala, valb, valc; };
void init(int x) {qpowa[0] = qpowb[0] = qpowc[0] = 1;for(int i = 1; i <= x; i++) qpowa[i] = 1ll * qpowa[i - 1] * G % moda, qpowb[i] = 1ll * qpowb[i - 1] * G % modb, qpowc[i] = 1ll * qpowc[i - 1] * G % modc;}
bool operator == (thash aa, thash bb) {return aa.vala == bb.vala && aa.valb == bb.valb && aa.valc == bb.valc;}
bool operator < (thash aa, thash bb) {return aa.vala == bb.vala ? (aa.valb == bb.valb ? aa.valc < bb.valc : aa.valb < bb.valb) : aa.vala < bb.vala; }
bool operator > (thash aa, thash bb) {return aa.vala == bb.vala ? (aa.valb == bb.valb ? aa.valc > bb.valc : aa.valb > bb.valb) : aa.vala > bb.vala; }
thash operator + (thash aa, int bb) {thash p;p.vala = ((aa.vala + bb) % moda + moda) % moda;p.valb = ((aa.valb + bb) % modb + modb) % modb;p.valc = ((aa.valc + bb) % modc + modc) % modc;return p;}
thash operator + (thash aa, thash bb) {thash p; p.vala = ((aa.vala + bb.vala) % moda + moda) % moda; p.valb = ((aa.valb + bb.valb) % modb + modb) % modb;p.valc = ((aa.valc + bb.valc) % modc + modc) % modc; return p;}
thash operator * (thash aa, int bb) { thash p; p.vala = 1ll * aa.vala * (bb + moda) % moda; p.valb = 1ll * aa.valb * (bb + modc) % modb; p.valc = 1ll * aa.valc * (bb + modc) % modc; return p;}
thash operator << (thash aa, int bb) { thash p; p.vala = 1ll * aa.vala * qpowa[bb] % moda; p.valb = 1ll * aa.valb * qpowb[bb] % modb; p.valc = 1ll * aa.valc * qpowc[bb] % modc; return p; }
thash make(int aa) { thash p; p.vala = (aa % moda + moda) % moda; p.valb = (aa % modb + modb) % modb; p.valc = (aa % modc + modc) % modc; return p; }
thash clean() {thash p; p.vala = p.valb = p.valc = 0; return p;}
// end hash ----------------------------------------
CF514C Watto and Mechanism
用 map 维护三哈希做出每一个答案是YES
的字符串, 然后查询在 map 中查询就好了。
CF1200E Compress Words
用哈希一位一位匹配看最多能匹配几位就行了。
CF504E Misha and LCP on Tree
二分答案,然后哈希判定可不可行。暴力 \(n \log ^2 n\) 可过
CF356E Xenia and String Problem
考虑最终的串的个数是 \(n \log n\) 级别的,可以倍增判断是否满足。
而且把一个串修理成一个gray
的串,在倍增上执行计算 lcp, 判断两个串是否相同 等操作,可以一个哈希解决。
CF961F k-substrings
其实这题的重点不是哈希(
考虑到 \(ans_i \le ans_{i + 1} + 1\), 于是从后往前暴力做一遍就好了。复杂度是对的
CF452F Permutation,P2757 [国家集训队]等差子序列
考虑枚举中间的那个节点,如果我们遍历了一个前缀,记录出现的数存在 \(vis\) 数组内。
如果 \(vis_{a_i - x} \oplus vis_{a_i + x} = 1\)(\(x \le \min(a_i - 1, n - a_i)\)),那么答案就是YES
。
问题转化为判断 \(vis_{a_i - x... a_i}\) 和 \(reverse_{vis_{a_i....a_i + x}}\) 是否相同。这个用哈希 + 树状数组解决。