Problem:
Problem
$N$ 頂点の根付き木が与えられます。
各頂点には $0$ から $N-1$ の重複のない番号がついていて、頂点 $0$ が根です。
$j$ 番目の辺は頂点 $u_j$ と $v_j$ を結んでいます。
頂点 $i$ には $C_i$ 個のコマが置いてあります。
Aizu君とBeet君はゲームをします。
ゲームでは、Aizu君から始めて交互に以下の操作を行います。
子の存在する頂点 $w$ に置かれたコマを一個選ぶ。
$w$ の子孫であって、$w$ との距離が $1$ 以上 $K$ 以下であるような頂点のうち一つを選び、そこに選んだコマを移動する。
先に操作ができなくなった方が負けです。
両者が最適に行動したとき、どちらが勝つか求めてください。
Input
入力は以下の形式で与えられる。
$N$ $K$
$C_0$ $C_1$ $\ldots$ $C_{N-1}$
$u_0$ $v_0$
$\vdots$
$u_{N-2}$ $v_{N-2}$
Constraints
入力は以下の条件を満たす。
$2 \leq N \leq 10^5$
$1 \leq K \leq 100$
$0 \leq C_i \leq 10^{5}$
$0 \leq u_j,v_j \leq N-1$
$( \sum_{i=0}^{N-1} C_i ) \geq 1$
与えられるグラフは木である
入力は全て整数である
Output
Aizu君が勝つなら"Aizu"を、Beet君が勝つなら"Beet"を一行に出力する。
Sample Input 1
2 100
0 1
1 0
Sample Output 1
Beet
Sample Input 2
7 3
1 1 1 1 1 1 1
0 1
1 2
2 3
1 4
1 5
4 6
Sample Output 2
Aizu

Submitted solutions:

code_snippet: #include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define rep(i, m, n) for (ll i = (ll)m; i < (ll)n; i++)
#define drep(i, m, n) for (ll i = m - 1; i >= n; i--)
#define Endl endl
#define all(a) a.begin(), a.end()
#define pr(i, j) make_pair(i, j)
#define isin(x, l, r) (l <= x && x < r)
#define chmin(a, b) a = min(a, b)
#define chmax(a, b) a = max(a, b)
#define srt(ar) sort(ar.begin(), ar.end())
#define rev(ar) reverse(ar.begin(), ar.end())
#define jge(f, s, t) cout << (f ? s : t) << endl
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#define printar(ar)             \
    do                          \
    {                           \
        for (auto dbg : ar)     \
        {                       \
            cout << dbg << " "; \
        }                       \
        cout << endl;           \
    } while (0)
const ll inf = 1e18;
const ld pi = 3.14159265358979;
const ld eps = 1e-9;
template <class T, ll n, ll idx = 0>
auto make_vec(const ll (&d)[n], const T &init) noexcept
{
    if constexpr (idx < n)
        return std::vector(d[idx], make_vec<T, n, idx + 1>(d, init));
    else
        return init;
}

template <class T, ll n>
auto make_vec(const ll (&d)[n]) noexcept
{
    return make_vec(d, T{});
}
//////////////// 以下を貼る ////////////////
template <class T>
size_t HashCombine(const size_t seed, const T &v)
{
    return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
/* pair用 */
template <class T, class S>
struct std::hash<std::pair<T, S>>
{
    size_t operator()(const std::pair<T, S> &keyval) const noexcept
    {
        return HashCombine(std::hash<T>()(keyval.first), keyval.second);
    }
};
////////////////////////////////////////////
ll mex(vector<bool> a)
{
    ll ret = 0;
    rep(i, 0, a.size())
    {
        if (!a[i])
        {
            break;
        }
        ret++;
    }
    return ret;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll n, K;
    cin >> n >> K;
    vector<ll> c(n);
    rep(i, 0, n)
    {
        cin >> c[i];
    }
    vector<vector<ll>> g(n);
    vector<pair<ll, ll>> d(n);
    vector<vector<bool>> G(n, vector<bool>(200, false));
    rep(i, 0, n - 1)
    {
        ll u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    rep(i, 0, n)
    {
        d[i].second = i;
    }
    vector<ll> from(n, -1);
    queue<ll> q, q2;
    vector<bool> v(n);
    vector<ll> grundy(n);
    q.push(0);
    v[0] = true;
    while (!q.empty())
    {
        ll now = q.front();
        q.pop();
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i];
            if (!v[nxt])
            {
                v[nxt] = true;
                q.push(nxt);
                from[nxt] = now;
                d[nxt].first = d[now].first + 1;
            }
        }
    }
    srt(d);
    rev(d);
    rep(i, 0, n)
    {
        ll now = d[i].second;
        ll t = mex(G[now]);
        grundy[now] = t;
        rep(j, 0, K)
        {
            if (now == 0)
            {
                break;
            }
            now = from[now];
            G[now][t] = true;
        }
    }
    ll x = 0;
    rep(i, 0, n)
    {
        if (c[i] % 2 == 1)
        {
            x ^= grundy[i];
        }
    }
    if (x == 0)
    {
        cout << "Beet" << endl;
    }
    else
    {
        cout << "Aizu" << endl;
    }
}
accuracy: 1
time_ms: 30
memory_kb: 22528
final_rank: 2

code_snippet: // AOJ #3089 Game on Tree
// 2025.2.22

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

int N, K;
vector<int> coins;
vector<vector<int>> tree;

const int MAX_M = 82;

int mex(const bitset<MAX_M> &bs) {
    for (int i = 0; i < MAX_M; i++){
        if (!bs.test(i)) return i;
    }
    return MAX_M;
}

vector<bitset<MAX_M>> dfs(int u, int parent, vector<int>& grundy) {
    vector<bitset<MAX_M>> dp(K);
    bool isLeaf = true;

    for (int v : tree[u]) {
        if (v == parent) continue;
        isLeaf = false;
        vector<bitset<MAX_M>> child_dp = dfs(v, u, grundy);
        bitset<MAX_M> tmp;
        tmp.reset();
        tmp.set(grundy[v]);
        dp[0] |= tmp;
        for (int d = 1; d < K; d++) dp[d] |= child_dp[d-1];
    }

    bitset<MAX_M> S;
    S.reset();
    for (int d = 0; d < K; d++) S |= dp[d];

    if (isLeaf) grundy[u] = 0;
    else        grundy[u] = mex(S);
    return dp;
}

int main() {
    N = Cin(), K = Cin();
    coins.resize(N);
    for (int i = 0; i < N; i++) coins[i] = Cin();

    vector<vector<int>> graph(N);
    for (int i = 0; i < N-1; i++){
        int u = Cin(), v = Cin();
        graph[u].push_back(v);
        graph[v].push_back(u);
    }
    tree.assign(N, vector<int>());
    vector<int> parent(N, -1);
    deque<int> dq;
    dq.push_back(0);
    parent[0] = -1;
    while(!dq.empty()){
        int u = dq.front();
        dq.pop_front();
        for (int w : graph[u]){
            if(w == parent[u]) continue;
            parent[w] = u;
            tree[u].push_back(w);
            dq.push_back(w);
        }
    }

    vector<int> grundy(N, 0);
    dfs(0, -1, grundy);

    int nim = 0;
    for (int i = 0; i < N; i++){
        if (coins[i] % 2 == 1) nim ^= grundy[i];
    }
    printf(nim? "Aizu\n": "Beet\n");
    return 0;
}
accuracy: 0.1111111111111111
time_ms: 20
memory_kb: 12168
final_rank: 18

code_snippet: // AOJ #3089 Game on Tree
// 2025.2.22

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

int N, K;
vector<int> coins;
vector<vector<int>> tree;

const int MAX_M = 100;

int mex(const bitset<MAX_M> &bs) {
    for (int i = 0; i < MAX_M; i++){
        if (!bs.test(i)) return i;
    }
    return MAX_M;
}

vector<bitset<MAX_M>> dfs(int u, int parent, vector<int>& grundy) {
    vector<bitset<MAX_M>> dp(K);
    bool isLeaf = true;

    for (int v : tree[u]) {
        if (v == parent) continue;
        isLeaf = false;
        vector<bitset<MAX_M>> child_dp = dfs(v, u, grundy);
        bitset<MAX_M> tmp;
        tmp.reset();
        tmp.set(grundy[v]);
        dp[0] |= tmp;
        for (int d = 1; d < K; d++) dp[d] |= child_dp[d-1];
    }

    bitset<MAX_M> S;
    S.reset();
    for (int d = 0; d < K; d++) S |= dp[d];

    if (isLeaf) grundy[u] = 0;
    else        grundy[u] = mex(S);
    return dp;
}

int main() {
    N = Cin(), K = Cin();
    coins.resize(N);
    for (int i = 0; i < N; i++) coins[i] = Cin();

    vector<vector<int>> graph(N);
    for (int i = 0; i < N-1; i++){
        int u = Cin(), v = Cin();
        graph[u].push_back(v);
        graph[v].push_back(u);
    }
    tree.assign(N, vector<int>());
    vector<int> parent(N, -1);
    deque<int> dq;
    dq.push_back(0);
    parent[0] = -1;
    while(!dq.empty()){
        int u = dq.front();
        dq.pop_front();
        for (int w : graph[u]){
            if(w == parent[u]) continue;
            parent[w] = u;
            tree[u].push_back(w);
            dq.push_back(w);
        }
    }

    vector<int> grundy(N, 0);
    dfs(0, -1, grundy);

    int nim = 0;
    for (int i = 0; i < N; i++){
        if (coins[i] % 2 == 1) nim ^= grundy[i];
    }
    printf(nim? "Aizu\n": "Beet\n");
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 33820
final_rank: 3

code_snippet: // AOJ #3089 Game on Tree
// 2025.2.22

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

int N, K;
vector<int> coins;
vector<vector<int>> tree;

const int MAX_M = 128;

int mex(const bitset<MAX_M> &bs) {
    for (int i = 0; i < MAX_M; i++){
        if (!bs.test(i)) return i;
    }
    return MAX_M;
}

vector<bitset<MAX_M>> dfs(int u, int parent, vector<int>& grundy) {
    vector<bitset<MAX_M>> dp(K);
    bool isLeaf = true;

    for (int v : tree[u]) {
        if (v == parent) continue;
        isLeaf = false;
        vector<bitset<MAX_M>> child_dp = dfs(v, u, grundy);
        bitset<MAX_M> tmp;
        tmp.reset();
        tmp.set(grundy[v]);
        dp[0] |= tmp;
        for (int d = 1; d < K; d++) dp[d] |= child_dp[d-1];
    }

    bitset<MAX_M> S;
    S.reset();
    for (int d = 0; d < K; d++) S |= dp[d];

    if (isLeaf) grundy[u] = 0;
    else        grundy[u] = mex(S);
    return dp;
}

int main() {
    N = Cin(), K = Cin();
    coins.resize(N);
    for (int i = 0; i < N; i++) coins[i] = Cin();

    vector<vector<int>> graph(N);
    for (int i = 0; i < N-1; i++){
        int u = Cin(), v = Cin();
        graph[u].push_back(v);
        graph[v].push_back(u);
    }
    tree.assign(N, vector<int>());
    vector<int> parent(N, -1);
    deque<int> dq;
    dq.push_back(0);
    parent[0] = -1;
    while(!dq.empty()){
        int u = dq.front();
        dq.pop_front();
        for (int w : graph[u]){
            if(w == parent[u]) continue;
            parent[w] = u;
            tree[u].push_back(w);
            dq.push_back(w);
        }
    }

    vector<int> grundy(N, 0);
    dfs(0, -1, grundy);

    int nim = 0;
    for (int i = 0; i < N; i++){
        if (coins[i] % 2 == 1) nim ^= grundy[i];
    }
    printf(nim? "Aizu\n": "Beet\n");
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 33744
final_rank: 5

code_snippet: // AOJ #3089 Game on Tree
// 2025.2.22

#include <bits/stdc++.h>
using namespace std;

int N, K;
vector<int> coins;
vector<vector<int>> tree;

const int MAX_M = 128;

int mex(const bitset<MAX_M> &bs) {
    for (int i = 0; i < MAX_M; i++){
        if (!bs.test(i)) return i;
    }
    return MAX_M;
}

vector<bitset<MAX_M>> dfs(int u, int parent, vector<int>& grundy) {
    vector<bitset<MAX_M>> dp(K);
    bool isLeaf = true;

    for (int v : tree[u]) {
        if (v == parent) continue;
        isLeaf = false;
        vector<bitset<MAX_M>> child_dp = dfs(v, u, grundy);
        bitset<MAX_M> tmp;
        tmp.reset();
        tmp.set(grundy[v]);
        dp[0] |= tmp;
        for (int d = 1; d < K; d++) dp[d] |= child_dp[d-1];
    }

    bitset<MAX_M> S;
    S.reset();
    for (int d = 0; d < K; d++) S |= dp[d];

    if (isLeaf) grundy[u] = 0;
    else        grundy[u] = mex(S);
    return dp;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> K;
    coins.resize(N);
    for (int i = 0; i < N; i++) cin >> coins[i];

    vector<vector<int>> graph(N);
    for (int i = 0; i < N-1; i++){
        int u, v;
        cin >> u >> v;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }
    tree.assign(N, vector<int>());
    vector<int> parent(N, -1);
    deque<int> dq;
    dq.push_back(0);
    parent[0] = -1;
    while(!dq.empty()){
        int u = dq.front();
        dq.pop_front();
        for (int w : graph[u]){
            if(w == parent[u]) continue;
            parent[w] = u;
            tree[u].push_back(w);
            dq.push_back(w);
        }
    }

    vector<int> grundy(N, 0);
    dfs(0, -1, grundy);

    int nim = 0;
    for (int i = 0; i < N; i++){
        if (coins[i] % 2 == 1) nim ^= grundy[i];
    }
    cout << (nim != 0 ? "Aizu" : "Beet") << endl;
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 33860
final_rank: 6

code_snippet: // AOJ #3089
// Game on Tree 2025.2.6

#include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;
 
// ----- Bitset128: 128ビット分のビット集合（最大グランディ値はK+1 <= 102となるので十分） -----
struct Bitset128 {
    ull a, b; // 下位64ビット: a, 上位: b（0〜127のビットを使う）
};
 
// 空のビット集合
inline Bitset128 bs_empty() {
    return {0ULL, 0ULL};
}
 
// ひとつのビットだけ立てたビット集合（位置 pos に立てる）
inline Bitset128 bs_single(int pos) {
    Bitset128 ret;
    ret.a = 0; ret.b = 0;
    if(pos < 64) {
        ret.a = 1ULL << pos;
    } else {
        ret.b = 1ULL << (pos - 64);
    }
    return ret;
}
 
// OR（和集合）
inline Bitset128 bs_or(const Bitset128 &x, const Bitset128 &y) {
    Bitset128 ret;
    ret.a = x.a | y.a;
    ret.b = x.b | y.b;
    return ret;
}
 
// 指定ビットが立っているか
inline bool bs_test(const Bitset128 &x, int pos) {
    if(pos < 64) return ((x.a >> pos) & 1ULL) != 0;
    else return ((x.b >> (pos-64)) & 1ULL) != 0;
}
 
// mex: [0, maxVal) の中で x に含まれない最小の数を返す
int bs_mex(const Bitset128 &x, int maxVal) {
    for (int i = 0; i < maxVal; i++){
        if(!bs_test(x, i)) return i;
    }
    return maxVal; // 通常はここに来ない
}
 
// ----- セグメントツリー（各ノードは Bitset128 を保持，OR をとる）
struct SegTree {
    int n;
    vector<Bitset128> tree;
    SegTree() : n(0) {}
    SegTree(int sz) {
        n = sz;
        tree.assign(2 * n, bs_empty());
    }
    // pos (0-indexed) の位置に val を OR で更新
    void update(int pos, const Bitset128 &val) {
        pos += n;
        tree[pos] = bs_or(tree[pos], val);
        for(pos /= 2; pos >= 1; pos /= 2) {
            tree[pos] = bs_or(tree[2*pos], tree[2*pos+1]);
        }
    }
    // 区間 [l, r) の OR を返す
    Bitset128 query(int l, int r) {
        Bitset128 res = bs_empty();
        for(l += n, r += n; l < r; l /= 2, r /= 2) {
            if(l & 1) {
                res = bs_or(res, tree[l]);
                l++;
            }
            if(r & 1) {
                r--;
                res = bs_or(res, tree[r]);
            }
        }
        return res;
    }
};
 
// ----- 木の DFS・Euler Tour 関連 -----
int N, K;
vector<vector<int>> children;
vector<int> C;
vector<int> inTime, outTime, depth;
vector<int> euler;
int timer = 0;
 
void dfs(int v, int d) {
    depth[v] = d;
    inTime[v] = timer++;
    euler.push_back(v);
    for (int nxt : children[v]) {
        dfs(nxt, d+1);
    }
    outTime[v] = timer;
}
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
 
    cin >> N >> K;
    C.resize(N);
    for (int i = 0; i < N; i++) cin >> C[i];

    // 入力は辺が N-1 本与えられる．
    // 頂点番号は 0～N-1 で，0 が根．
    vector<vector<int>> adj(N);
    for (int i = 0; i < N-1; i++){
        int u, v;
        cin >> u >> v;
        // 無向グラフとして読み込み
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    // 0 を根として木を構築．
    children.assign(N, vector<int>());
    inTime.resize(N); outTime.resize(N); depth.resize(N);
    vector<int> parent(N, -1);
    {
        queue<int> q;
        q.push(0);
        parent[0] = -1;
        depth[0] = 0;
        while(!q.empty()){
            int cur = q.front(); q.pop();
            for (int nxt : adj[cur]) {
                if(nxt == parent[cur]) continue;
                parent[nxt] = cur;
                depth[nxt] = depth[cur] + 1;
                children[cur].push_back(nxt);
                q.push(nxt);
            }
        }
    }
    // Euler Tour を DFS で求める
    timer = 0;
    euler.clear();
    dfs(0, 0);
 
    // 部分木の区間 [in[v], out[v]) が得られる．
    // また，各頂点の深さも depth[v] に格納されている．
    int maxDepth = 0;
    for (int i = 0; i < N; i++){
        maxDepth = max(maxDepth, depth[i]);
    }
 
    // 各深さ d について，Euler 順序でのインデックスのリストを作る
    vector<vector<int>> depthList(maxDepth+1);
    for (int i = 0; i < N; i++){
        depthList[ depth[i] ].push_back(inTime[i]);
    }
    for (int d = 0; d <= maxDepth; d++){
        sort(depthList[d].begin(), depthList[d].end());
    }
 
    vector<SegTree> segTrees(maxDepth+1);
    for (int d = 0; d <= maxDepth; d++){
        int sz = depthList[d].size();
        if(sz > 0) segTrees[d] = SegTree(sz);
    }
 
    vector<int> grundy(N, 0);
    vector<int> order = euler;
    reverse(order.begin(), order.end());
 
    for (int v : order) {
        int d = depth[v];
        Bitset128 unionBS = bs_empty();
        int L = inTime[v] + 1;
        int R = outTime[v];
        int lowDepth = d + 1;
        int highDepth = min(maxDepth, d + K);
        for (int nd = lowDepth; nd <= highDepth; nd++){
            if(depthList[nd].empty()) continue;
            int lpos = int(lower_bound(depthList[nd].begin(), depthList[nd].end(), L) - depthList[nd].begin());
            int rpos = int(lower_bound(depthList[nd].begin(), depthList[nd].end(), R) - depthList[nd].begin());
            if(lpos < rpos) {
                Bitset128 segRes = segTrees[nd].query(lpos, rpos);
                unionBS = bs_or(unionBS, segRes);
            }
        }
        int gVal = bs_mex(unionBS, K+2);
        grundy[v] = gVal;
        int pos = int(lower_bound(depthList[d].begin(), depthList[d].end(), inTime[v]) - depthList[d].begin());
        segTrees[d].update(pos, bs_single(gVal));
    }
 
    int nimXor = 0;
    for (int i = 0; i < N; i++){
        if(C[i] % 2 == 1) {
            nimXor ^= grundy[i];
        }
    }
    cout << (nimXor != 0 ? "Aizu" : "Beet") << endl;
    return 0;
}
accuracy: 0.5185185185185185
time_ms: 60
memory_kb: 18800
final_rank: 17

code_snippet: #include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
#include <stack>
#include  <map>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=100005,K=105;
int n,k;
int dp[maxn][K*2];
int c[maxn];
int tai[maxn];
int fa[maxn];
vector<int> e[maxn];
void dfs(int x,int p)
{
    fa[x]=p;
    for(int i=0;i<(int)e[x].size();i++){
        int to=e[x][i];
        if(to==p) continue;
        dfs(to,x);
    }
    int t=0;
    while(t<2*K){
        if(dp[x][t]){
            t++;
        }
        else{
            break;
        }
    }
    tai[x]=t;
    int now=p;
    for(int i=0;i<k;i++){
        if(now!=-1) dp[now][t]=1;
        else break;
        now=fa[now];
    }
}
int main()
{
    ios::sync_with_stdio(false),cin.tie(0);
    cin>>n>>k;
    for(int i=0;i<n;i++) cin>>c[i];
    int a,b;
    for(int i=0;i<n-1;i++){
        cin>>a>>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    dfs(0,-1);
    int ans=0;
    for(int i=0;i<n;i++){
        if(c[i]&1) ans^=tai[i];
    }
    if(ans==0) cout<<"Beet"<<endl;
    else cout<<"Aizu"<<endl;
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 76624
final_rank: 9

code_snippet: #include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
#include <stack>
#include  <map>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=100005,K=105;
int n,k;
int dp[maxn][K];
int c[maxn];
int tai[maxn];
int fa[maxn];
vector<int> e[maxn];
void dfs(int x,int p)
{
    fa[x]=p;
    for(int i=0;i<(int)e[x].size();i++){
        int to=e[x][i];
        if(to==p) continue;
        dfs(to,x);
    }
    int t=0;
    while(t<k){
        if(dp[x][t]){
            t++;
        }
        else{
            break;
        }
    }
    tai[x]=t;
    int now=p;
    for(int i=0;i<k;i++){
        if(now!=-1) dp[now][t]=1;
        else break;
        now=fa[now];
    }
}
int main()
{
    ios::sync_with_stdio(false),cin.tie(0);
    cin>>n>>k;
    for(int i=0;i<n;i++) cin>>c[i];
    int a,b;
    for(int i=0;i<n-1;i++){
        cin>>a>>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    dfs(0,-1);
    int ans=0;
    for(int i=0;i<n;i++){
        if(c[i]&1) ans^=tai[i];
    }
    if(ans==0) cout<<"Beet"<<endl;
    else cout<<"Aizu"<<endl;
    return 0;
}
accuracy: 0.09259259259259259
time_ms: 40
memory_kb: 44236
final_rank: 19

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;




#define SIZE 100005


int N,K;
int PARENT[SIZE];
ll C[SIZE],GRUNDY[SIZE];
vector<int> G[SIZE];
map<ll,bool> MAP[SIZE];



void dfs(int node_id,int pre){

	PARENT[node_id] = pre;

	for(int i = 0; i < G[node_id].size(); i++){

		int child = G[node_id][i];
		if(child == pre)continue;

		dfs(child,node_id);
	}

	ll value;

	for(value = 0; ; value++){

		auto at = MAP[node_id].find(value);

		if(at == MAP[node_id].end()){

			break;
		}
	}

	GRUNDY[node_id] = value;

	int now = node_id;

	for(int i = 0; i < K; i++){

		int tmp_p = PARENT[now];
		if(tmp_p == -1)break;

		MAP[tmp_p][value] = true;
		now = PARENT[now];
	}
}


int main(){

	scanf("%d %d",&N,&K);

	for(int i = 0; i < N; i++){

		scanf("%lld",&C[i]);
	}

	int a,b;
	for(int loop = 0; loop < N-1; loop++){

		scanf("%d %d",&a,&b);

		G[a].push_back(b);
		G[b].push_back(a);
	}

	for(int i = 0; i < N; i++){

		PARENT[i] = -1;
	}

	dfs(0,-1);

	ll XOR = 0;

	for(int i = 0; i < N; i++){
		if(C[i]%2 == 0)continue;

		XOR ^= GRUNDY[i];
	}

	if(XOR == 0){

		printf("Beet\n");
	}else{

		printf("Aizu\n");
	}

	return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 159600
final_rank: 15

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;




#define SIZE 100005


int N,K;
int PARENT[SIZE];
ll C[SIZE],GRUNDY[SIZE];
vector<int> G[SIZE];
map<ll,bool> MAP[SIZE];



void dfs(int node_id,int pre){

	PARENT[node_id] = pre;

	for(int i = 0; i < G[node_id].size(); i++){

		int child = G[node_id][i];
		if(child == pre)continue;

		dfs(child,node_id);
	}

	ll value;

	for(value = 0; ; value++){

		auto at = MAP[node_id].find(value);

		if(at == MAP[node_id].end()){

			break;
		}
	}

	GRUNDY[node_id] = value;

	int now = node_id;

	for(int i = 0; i < K; i++){

		int tmp_p = PARENT[now];
		if(tmp_p == -1)break;

		MAP[tmp_p][tmp_p] = true;
		now = PARENT[node_id];
	}
}


int main(){

	scanf("%d %d",&N,&K);

	for(int i = 0; i < N; i++){

		scanf("%lld",&C[i]);
	}

	int a,b;
	for(int loop = 0; loop < N-1; loop++){

		scanf("%d %d",&a,&b);

		G[a].push_back(b);
		G[b].push_back(a);
	}

	for(int i = 0; i < N; i++){

		PARENT[i] = -1;
	}

	dfs(0,-1);

	ll XOR = 0;

	for(int i = 0; i < N; i++){
		if(C[i]%2 == 0)continue;

		XOR ^= GRUNDY[i];
	}

	if(XOR == 0){

		printf("Beet\n");
	}else{

		printf("Aizu\n");
	}

	return 0;
}
accuracy: 0.018518518518518517
time_ms: 40
memory_kb: 16556
final_rank: 20

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 100005


int N,K;
int C[SIZE],parent[SIZE],GRUNDY[SIZE];
set<int> SET[SIZE];
vector<int> G[SIZE];

void dfs(int node_id,int pre){

	parent[node_id] = pre;

	for(int i = 0; i < G[node_id].size(); i++){

		int child = G[node_id][i];
		if(child == pre)continue;

		dfs(child,node_id);
	}

	int num;

	for(num = 0; ; num++){

		if(SET[node_id].count(num) == 0){

			GRUNDY[node_id] = num;
			break;
		}
	}

	int now = node_id;

	for(int i = 0; i < K; i++){
		int tmp = parent[now];
		if(tmp == -1)break;

		SET[tmp].insert(num);
		now = tmp;
	}
}

int main(){

	scanf("%d %d",&N,&K);

	for(int i = 0; i < N; i++){

		scanf("%d",&C[i]);
	}

	int a,b;

	for(int i = 0; i < N-1; i++){

		scanf("%d %d",&a,&b);
		G[a].push_back(b);
		G[b].push_back(a);
	}

	dfs(0,-1);

	int XOR = 0;

	for(int i = 0; i < N; i++){
		if(C[i]%2 == 0)continue;

		XOR ^= GRUNDY[i];
	}

	if(XOR == 0){

		printf("Beet\n");

	}else{

		printf("Aizu\n");
	}

	return 0;
}
accuracy: 1
time_ms: 380
memory_kb: 122560
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct tree{
  vector<vector<int>> G,son,ancestor;
  vector<int> depth,parent;
  queue<int> que;
  int n,root=-1;
  bool made_lca=false;

  tree(int n_):G(n_),son(n_),parent(n_,-1),depth(n_,-1),ancestor(n_),n(n_){
    for(int i=0;i<n_;i++)ancestor[i].resize(30);
  }

  void add_edge(int u,int v){
    G[u].push_back(v);
    G[v].push_back(u);
  }

  inline void reset_root(){
    root=-1;
    fill(depth.begin(),depth.end(),-1);
    fill(parent.begin(),parent.end(),-1);
    for(auto &p:ancestor)for(int &q:p)q=-1;
    for(auto &p:son)p.resize(0);
    made_lca=false;
  }

  void have_root(int r){
    reset_root();
    root=r;
    que.push(r);
    while(que.size()){
      int p=que.front();que.pop();
      for(int q:G[p]){
        if(parent[p]==q)continue;
        son[p].push_back(q);
        parent[q]=p;
        que.push(q);
      }
    }
  }

  void set_depth(){
    assert(~root);
    depth[root]=0;
    que.push(root);
    while(que.size()){
      int p=que.front();que.pop();
      for(int q:son[p]){
        depth[q]=depth[p]+1;
        que.push(q);
      }
    }
  }

  inline void make_lca(){
    assert(~root);
    if(depth[root]<0)set_depth();
    for(int i=0;i<G.size();i++)ancestor[i][0]=parent[i];
    for(int j=1;j<30;j++)
      for(int i=0;i<G.size();i++)
        if(~ancestor[i][j-1])
          ancestor[i][j]=ancestor[ancestor[i][j-1]][j-1];
    made_lca=1;
  }

  int lca(int u,int v){
    if(!made_lca)make_lca();
    if(depth[u]>depth[v])swap(u,v);
    int diff=depth[v]-depth[u],cnt=0;
    while(diff){
      if(diff&1)v=ancestor[v][cnt];
      cnt++;
      diff>>=1;
    }
    if(u==v)return u;
    for(int k=28;k>=0;k--)
      if(ancestor[u][k]!=ancestor[v][k])
        u=ancestor[u][k],v=ancestor[v][k];
    return ancestor[u][0];
  }

};

signed main(){
  int n,k;cin>>n>>k;
  tree t(n);
  vector<int> v(n);
  for(int i=0;i<n;i++)cin>>v[i];
  for(int i=1;i<n;i++){
    int U,V;cin>>U>>V;
    t.add_edge(U,V);
  }
  t.have_root(0);
  queue<int> que;
  vector<int> in(n);
  for(int i=0;i<n;i++){
    in[i]=t.son[i].size();
    if(!in[i])que.push(i);
  }
  vector<bool> used(n+3,0);
  vector<int> grun(n,-1);
  int ans=0;
  t.set_depth();
  while(que.size()){
    int p=que.front();que.pop();
    stack<int> sta;
    for(int q:t.son[p])sta.push(q);
    int cnt=0;
    while(sta.size()){
      int q=sta.top();sta.pop();cnt++;
      used[grun[q]]=1;
      if(t.depth[q]-t.depth[p]<k)
        for(int x:t.son[q])sta.push(x);
    }
    for(int i=0;i<=cnt+1;i++){
      if(!used[i]&&grun[p]<0)grun[p]=i;
      used[i]=0;
    }
    if(v[p]&1)ans^=grun[p];
    if(p){
      int P=t.parent[p];
      if(--in[P]==0)que.push(P);
    }
  }
  if(ans)cout<<"Aizu"<<endl;
  else cout<<"Beet"<<endl;
}
accuracy: 1
time_ms: 120
memory_kb: 28716
final_rank: 10

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 19;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

struct Data {
	multiset<int> st;
	multiset<P> d;
};
void merge(Data& a, Data& b) {
	if (a.d.size() < b.d.size()) {
		swap(a, b);
	}
	for (P p : b.d) {
		a.d.insert(p);
	}
	for (int x : b.st) {
		a.st.insert(x);
	}
}
int query(multiset<int>& s) {
	rep(i, 100000000) {
		if (s.find(i) == s.end())return i;
	}
	return 0;
}

void solve() {
	int n, k; cin >> n >> k;
	vector<int> c(n);
	rep(i, n)cin >> c[i];
	vector<vector<int>> G(n);
	rep(i, n - 1) {
		int a, b; cin >> a >> b;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	vector<int> g(n);
	function<Data(int, int, int)> dfs = [&](int id, int fr, int d)->Data {
		Data res;
		for (int to : G[id])if (to != fr) {
			Data nex = dfs(to, id, d + 1);
			merge(res, nex);
		}
		while (res.st.size()){
			P p = *res.d.rbegin();
			if (p.first > d + k) {
				res.d.erase(--res.d.end());
				res.st.erase(res.st.find(p.second));
			}
			else break;
		}
		int val = query(res.st);
		g[id] = val;
		res.st.insert(val);
		res.d.insert({ d,val });
		return res;
	};
	dfs(0, -1, 0);
	int x = 0;
	rep(i, n) {
		if (c[i] % 2)x ^= g[i];
	}
	if (x)cout << "Aizu\n";
	else cout << "Beet\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(15);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 27824
final_rank: 8

code_snippet: #include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include<set>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1000000007;

	
void dfs(int N, int K, vector<vector<int>> &tree, vector<int> &parent, int now, int par){
	
	parent[now] = par;
	
	for(int i = 0; i < tree[now].size(); i++){
		if(tree[now][i] == par) continue;
		dfs(N, K, tree, parent, tree[now][i], now);
		
	}
}

void solve(int N, int K, vector<vector<int>> &tree, vector<int> &mex, vector<set<int>> &move, vector<int> &parent, int now, int par){
	
	for(int i = 0; i < tree[now].size(); i++){
		if(tree[now][i] == par) continue;
		solve(N, K, tree, mex, move, parent, tree[now][i], now);
		
	}
	
	for(int i = 0; ; i++){
		if(move[now].count(i) == 0) {
			mex[now] = i;
			break;
		}
	}
	
	for(int i = 0, n = now; i < K; i++){
		if(parent[n] == -1) break;
		move[parent[n]].insert(mex[now]);
		n = parent[n];
	}
}

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);
	
	int N, K, ans = 0;
	vector<int> C, parent, mex;
	vector<vector<int>> tree;
	vector<set<int>> move;
	
	cin>>N>>K;
	
	C.resize(N);
	mex.resize(N);
	move.resize(N);
	tree.resize(N);
	parent.resize(N);
	
	for(int i = 0; i < N; i++){
		cin>>C[i];
	}
	
	for(int i = 0; i < N - 1; i++){
		int u, v;
		
		cin>>u>>v;
		
		tree[u].push_back(v);
		tree[v].push_back(u);
	}
	
	dfs(N, K, tree, parent, 0, -1);
	
	solve(N, K, tree, mex, move, parent, 0, -1);
	
	for(int i = 0; i < N; i++){
		if(C[i]%2) ans ^= mex[i];
	}
	
	cout<<(ans ? "Aizu" : "Beet")<<endl;
	
	return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 122092
final_rank: 12

code_snippet: #pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) FOR(i, 1, n+1)
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define LEN(x) (int)(x).size()
#define DUMP(x) cerr<<__LINE__<<' '<<#x<<"="<<(x)<<endl;
#define popcnt(x) __builtin_popcount(x)
#define popcntll(x) __builtin_popcountll(x)

using namespace std;
using lint = long long;
using pii =  pair<int, int>;
using pll =  pair<lint, lint>;
template <typename T> using vc = vector<T>;
template <typename T> using vvc = vector<vector<T>>;
template <typename T> inline bool chmax(T &a, T b){if(a<b){a = b; return true;} return false;}
template <typename T> inline bool chmin(T &a, T b){if(a>b){a = b; return true;} return false;}

const double PI = acos(-1);
constexpr lint ten(int n) {return n==0 ? 1 : ten(n-1)*10;}

class Task{
public:
    int N, K;
    vc<int> C, g, cnt, tmp;
    vvc<int> G;

    void dfs1(int s, int par){
        // sの各子孫のGrundy数を求める
        for(auto& to : G[s]){
            if(to==par) continue;
            dfs1(to, s);
        }
        // sのGrundy数を求める
        dfs2(s, par, K);
        int M = LEN(tmp);

        for(auto& t : tmp){
            if(t<=M) cnt[t]++; 
        }

        REP(i, M+1){
            if(cnt[i]==0){
                g[s] = i;
                break;
            }
        }

        fill(cnt.begin(), cnt.begin()+M+1, 0);
        tmp.clear();
    }

    void dfs2(int s, int par, int k){
        if(k){
            for(auto& to : G[s]){
                if(to==par) continue;
                dfs2(to, s, k-1);
                tmp.emplace_back(g[to]);
            }
        }
    }

    void run(){
        ios_base::sync_with_stdio(false);
        cin.tie(nullptr);
        cout.tie(nullptr);
        // input
        cin>>N>>K;
        C.resize(N);
        G.resize(N);
        REP(i, N) cin>>C[i];
        REP(i, N-1){
            int u, v;
            cin>>u>>v;
            G[u].emplace_back(v);
            G[v].emplace_back(u);
        }
        // solve
        solve();
    }

    void solve(){
        g.resize(N);
        cnt.resize(N+1, 0);
        dfs1(0, -1);

        int G = 0;
        REP(i, N){
            if(C[i]%2) G ^= g[i];
        }

        if(G) cout<<"Aizu\n";
        else cout<<"Beet\n";
    }
};

int main(){
    Task solver;
    solver.run();
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 10368
final_rank: 4

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<tuple>
#include<cassert>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (ll)1000000007 * 1000000007;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define Per(i,sta,n) for(int i=n-1;i>=sta;i--)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef long double ld;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<ll, ll> LP;
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
template<class T>bool chmax(T &a, const T &b) {if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T &a, const T &b) {if(b<a){a=b;return 1;}return 0;}

int n,k;
int c[100010],d[100010];
int dp[100010];
vector<int> G[100010];
map<int,int> ma[100010];

void dfs(int s,int par){
  if(par!=-1) d[s]=d[par]+1;
  for(int t:G[s]){
    if(t==par) continue;
    dfs(t,s);
    if(ma[t].size()>ma[s].size()) swap(ma[t],ma[s]);
    for(P p:ma[t]){
      if(ma[s][p.first]==0) ma[s][p.first]=p.second;
      else chmin(ma[s][p.first],p.second);
    }
  }
  rep(i,n){
    int h=ma[s][i];
    if(h!=0 && h-d[s]<=k) continue;
    dp[s]=i;
    ma[s][i]=d[s];
    return;
  }
}

void solve(){
  cin >> n >> k;
  rep(i,n) cin >> c[i];
  d[0]=1;
  rep(i,n-1){
    int u,v;cin >> u >> v;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  dfs(0,-1);
  int ans=0;
  rep(i,n){
    if(c[i]%2)ans^=dp[i];
  }
  // rep(i,n){
  //   cout << i << " " << d[i] << " " << dp[i] << endl;
  // }
  if(!ans) cout << "Beet" << endl;
  else cout << "Aizu" << endl;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(50);
    solve();
}
accuracy: 1
time_ms: 30
memory_kb: 19580
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int len = 317;

using B = bitset<len + 1>;

int n, k;
vector<vector<int>> g;
vector<int> c;
vector<vector<B>> memo;

bool solve();
void dfs(int now, int par, int &res);

int main() {
  cin >> n >> k;
  c.resize(n);
  for (auto &p : c) {
    cin >> p;
    p &= 1;
  }
  g.resize(n);
  for (int i = 1; i < n; ++i) {
    int a, b;
    cin >> a >> b;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  if (solve())
    cout << "Aizu" << endl;
  else
    cout << "Beet" << endl;
  return 0;
}

bool solve() {
  memo.resize(n, vector<B>(k + 1, 0));
  int res = 0;
  dfs(0, -1, res);
  return res;
}
void dfs(int now, int par, int &res) {
  for (auto to : g[now])
    if (to != par) {
      dfs(to, now, res);
      for (int i = 1; i <= k; ++i) memo[now][i] |= memo[to][i - 1];
    }
  B nb;
  for (auto b : memo[now]) nb |= b;
  for (int i = 0; i <= len; ++i)
    if (!nb[i]) {
      memo[now][0][i] = 1;
      if (c[now] & 1) res ^= i;
      break;
    }
}
accuracy: 1
time_ms: 260
memory_kb: 356484
final_rank: 16

code_snippet: #pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")

#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <queue>
#include <deque>
#include <algorithm>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <functional>
#include <cassert>
#include <iomanip>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d>>(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d)));
#define re(c, b) for(ll c=0;c<b;c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;

#define MAX_N 100001
vector<vector<int>> G(MAX_N);
vector<int> c(MAX_N), gr(MAX_N), d(MAX_N);
vector<vector<int>> b(MAX_N, vector<int>(331, 0));
int k;
typedef array<int, 2> ar;//
priority_queue<ar> q;

void dfs_d(int now, int from, int x){
  d[now] = x;
  for(auto to:G[now]){
    if(to==from) continue;
    dfs_d(to, now, x+1);
  }
}

void dfs(int now, int from){
  for(auto to:G[now]){
    if(to==from) continue;
    dfs(to, now);
    for(int i=0;i<331;i++) b[now][i] += b[to][i];
  }
  while(!q.empty()&&q.top()[0]-d[now]>k){
    b[now][gr[q.top()[1]]]--;
    q.pop();
  }
  int ret = 0;
  for(;ret<331;ret++) if(!b[now][ret]) break;
  gr[now] = ret;
  q.push(ar{d[now], now});
  b[now][gr[now]]++;//最後に追加
}

int main(){
  int n;scanf("%d %d", &n, &k);
  for(int i=0;i<n;i++) scanf("%d", &c[i]);
  for(int i=0;i<n-1;i++){
    int x, y;scanf("%d %d", &x, &y);
    G[x].push_back(y);
    G[y].push_back(x);
  }
  dfs_d(0, -1, 0);
  dfs(0, -1);
  int x = 0;
  for(int i=0;i<n;i++){
    if(c[i]%2==0) continue;
    else{
      x ^= gr[i];
    }
  }
  std::cout << (x?"Aizu":"Beet") << '\n';
}
accuracy: 1
time_ms: 90
memory_kb: 145136
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100100;

vector<int> g[N];
set<int> st[N];
int grundy[N];
int pre[N];
int k;

void dfs(int s,int p){
	if(p!=-1)pre[s]=p;
	for(int t:g[s]){
		if(t==p)continue;
		dfs(t,s);
	}
	int gru=0;
	while(1){
		if(st[s].find(gru)!=st[s].end()){
			gru++;
		}
		else{
			grundy[s]=gru;
			break;
		}
	}
	int P=p;
	for(int i=0;i<k;i++){
		if(P==-1)break;
		st[P].insert(gru);
		P=pre[P];
	}
}

int main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int n; cin >> n >> k;
	vector<int> c(n);
	for(int i=0;i<n;i++){
		cin >> c[i];
	}
	for(int i=1;i<n;i++){
		int x,y; cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs(0,-1);
	int a=0;
	for(int i=0;i<n;i++){
		if(c[i]%2){
			a^=grundy[i];
		}
	}
	if(a==0){
		printf("Beet\n");
	}
	else{
		printf("Aizu\n");
	}
}
accuracy: 1
time_ms: 370
memory_kb: 122376
final_rank: 13

code_snippet: #include "bits/stdc++.h"
using namespace std;
//#include "atcoder/all"
//using namespace atcoder;
#define int long long
#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define RREP(i, n) for (int i = (int)n - 1; i >= 0; --i)
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define RFOR(i, s, n) for (int i = (int)n - 1; i >= s; --i)
#define ALL(a) a.begin(), a.end()
#define IN(a, x, b) (a <= x && x < b)
template<class T>istream&operator >>(istream&is,vector<T>&vec){for(T&x:vec)is>>x;return is;}
template<class T>inline void out(T t){cout << t << "\n";}
template<class T,class... Ts>inline void out(T t,Ts... ts){cout << t << " ";out(ts...);}
template<class T>inline bool CHMIN(T&a,T b){if(a > b){a = b;return true;}return false;}
template<class T>inline bool CHMAX(T&a,T b){if(a < b){a = b;return true;}return false;}
constexpr int INF = 1e18;

signed main(){
	int N, K;
	cin >> N >> K;
	vector<int>c(N);
	REP(i, N) cin >> c[i];
	vector<vector<int>>g(N);
	REP(i, N - 1) {
		int a, b;
		cin >> a >> b;
		g[a].emplace_back(b);
		g[b].emplace_back(a);
	}
	vector<int>grundy(N);
	vector<vector<int>>depth(N);
	auto dfs = [&](auto&&f, int now, int par, int dep) -> vector<int> {
		vector<int>ret(111);
		for(auto e: g[now]) {
			if(e == par) continue;
			auto tmp = f(f, e, now, dep + 1);
			while(dep + K + 1 < N && depth[dep + K + 1].size()) {
				int t = depth[dep + K + 1].back();
				depth[dep + K + 1].pop_back();
				tmp[grundy[t]] -= 1;
			}
			REP(i, 111) {
				ret[i] += tmp[i];
			}
		}
		depth[dep].emplace_back(now);
		REP(i, 111) {
			if(ret[i] == 0) {
				grundy[now] = i;
				ret[i] |= 1;
				break;
			}
			if(i == 110) exit(EXIT_FAILURE);
		}
		return ret;
	};
	dfs(dfs, 0, -1, 0);
	int x = 0;
	REP(i, N) {
		if(c[i] % 2) x ^= grundy[i];
	}
	if(x) out("Aizu");
	else out("Beet");
}
accuracy: 1
time_ms: 70
memory_kb: 27356
final_rank: 7