树哈希

这种东西看代码比说话好用。

xor 多重集哈希

const ull mask=std::chrono::steady_clock::now().time_since_epoch().count();

int ull shift(ull x) {
	x^=mask, x^=x<<13, x^=x>>7, x^=x<<17, x^=mask;
	return x;
}

void dp(int x,int fa) {
	int ms=0; siz[x]=1;
	for(int y:to[x]) if(y^fa) dp(y,x), siz[x]+=siz[y], ms=max(ms,siz[y]);
	ms=max(ms,n-siz[x]);
	if(ms<=n/2) heart.pb(x);
}

void Hash(int x,int fa) {
	hsh[x]=1;
	for(int y:to[x]) if(y^fa) Hash(y,x), hsh[x]+=shift(hsh[y]);
	trees.insert(hsh[x]);
}

heart.clear(), dp(1,0);
for(int rt:heart) {
	trees.clear(), Hash(rt,0);
	qwq=max(trees,qwq);
}
// jury hash is qwq. 

质数表哈希

int vis[M], p[M], top;
void init() {
	int d=1299709;
	up(i,2,d) if(!vis[i]) {
		vis[i]=1, p[++top]=i;
		up(j,2,d/i) vis[i*j]=1;
	}
}

struct Tree {
	int n, siz[N]; ull hsh[N]; vector<int> to[N];
	void build(int x) { n=x; }
	void eadd(int u,int v) { to[u].pb(v), to[v].pb(u); }
	void Hash(int x,int fa) {
		hsh[x]=1, siz[x]=1;
		for(int y:to[x]) if(y^fa) Hash(y,x), siz[x]+=siz[y], hsh[x]+=hsh[y]*p[siz[y]];
	}
	void change(int x,int fa,int I) {
		if(fa) hsh[x]=hsh[x]+p[n-siz[x]]*(hsh[fa]-hsh[x]*p[siz[x]]);
		for(int y:to[x]) if(y^fa) change(y,x,I);
	}
};
posted @ 2024-03-31 19:39  Hypoxia571  阅读(2)  评论(0编辑  收藏  举报