树hash

发布时间 2023-06-20 11:47:51作者: 浪释归衣

Problem - G - Codeforces

树hash模板,使用的异或移位hash,为了防止被卡,弄了一个奇奇怪怪的数mask异或了下。

#include<bits/stdc++.h>
#define ull unsigned long long
#define fu(i, a, b) for(int i = (a), ed = (b); i <= ed; ++i)
#define fd(i, a, b) for(int i = (a), ed = (b); i >= ed; --i)
#define PRN(X) cout << #X << "=" << X << endl
#define PR(X) cout << #X << "=" << X << " "
using namespace std;

const int N = 2e5 + 5;

int read(){
    int f = 1, x = 0; char ch = getchar();
    while(ch > '9' || ch < '0'){     if(ch == '-')f = -1; ch = getchar(); }
    while(ch <= '9' && ch >= '0'){ x = (x << 1) + (x << 3) + (ch ^ 48);  ch = getchar(); }
    return x * f;
}
vector<int> G[N];
ull hs[N];

const ull mask = std::chrono::steady_clock::now().time_since_epoch().count();
ull xor_shift(int x) {
    x ^= mask;
    x ^= x << 13;
    x ^= x >> 7;
    x ^= x << 17;
    x ^= mask;
    return x;
}
void tree_hs(int u, int fa) {
    hs[u] = 1;
    for(auto v: G[u]) if(v != fa) {
        tree_hs(v, u);
        hs[u] += xor_shift(hs[v]);
    }
    
}
bool check(int u, int fa) {
    bool f = 1;
    unordered_map<ull, int> mp, rrk;
    for(auto v: G[u]) if(v != fa) mp[hs[v]]++, rrk[hs[v]] = v;
    int len = G[u].size(); if(u != 1)len--;
    for (auto it: mp) { 
        if(it.second & 1) { if(len & 1) len--, f = check(rrk[it.first], u); else { return false;}}
    }
    return f;
}
void solve(){
    
    int n = read();
    
    fu(i, 1, n - 1) {
        int u = read(), v = read();
        G[u].push_back(v), G[v].push_back(u); 
    }
    tree_hs(1, 0);

    check(1, 0) ? puts("Yes"):puts("No");
    
    fu(i, 1, n) G[i].clear();
}
int main(){
    int t = read();
    while(t--){
        solve();
    }
}