https://www.acwing.com/problem/content/description/159/ 树哈希千万不要用乘法,生成rand()的时候,以及进行哈希的时候都是,真的一个数有很多种因式分解的,冲突到飞起,还是移位然后异或比较
https://www.acwing.com/problem/content/description/159/
树哈希千万不要用乘法,生成rand()的时候,以及进行哈希的时候都是,真的一个数有很多种因式分解的,冲突到飞起,还是移位然后异或比较实在。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; ull ha[3005]; struct Tree { int root; vector<int> G[3005]; int siz[3005]; ull hashcode(int u) { siz[u] = 1; ull resu = 1; for(auto v : G[u]) { ull resv = hashcode(v); siz[u] += siz[v]; resu ^= (resv ^ ha[siz[v]]) + siz[v]; } return resu; } } t1, t2; char s1[3005], s2[3005]; int n1, id1, cur1; void build1(int u) { while(s1[cur1] == '0') { int v = ++id1; t1.G[u].push_back(v); ++cur1; build1(v); } ++cur1; return; } int n2, id2, cur2; void build2(int u) { while(s2[cur2] == '0') { int v = ++id2; t2.G[u].push_back(v); ++cur2; build2(v); } ++cur2; return; } int main() { #ifdef Yinku freopen("Yinku.in", "r", stdin); #endif // Yinku srand(time(0)); for(int i = 1; i <= 1501; ++i) { ha[i] = ((ull)rand() << 48) + ((ull)rand() << 32) + ((ull)rand() << 16) + (ull)rand(); } int t; scanf("%d", &t); while(t--) { scanf("%s%s", s1, s2); n1 = strlen(s1); n2 = strlen(s2); if(n1 != n2) puts("different"); else { id1 = 1, cur1 = 0; for(int i = 0; i <= 3001; ++i) { t1.G[i].clear(); t1.siz[i] = 0; } t1.root = 1; build1(id1); id2 = 1, cur2 = 0; for(int i = 0; i <= 3001; ++i) { t2.G[i].clear(); t2.siz[i] = 0; } t2.root = 1; build2(id2); ull res11 = t1.hashcode(1); ull res12 = t2.hashcode(1); puts((res11 == res12) ? "same" : "different"); } } }
是真的异或最实在,非常快,还均匀,乱得不行。