题解 | #游游的二进制树#

游游的二进制树

https://www.nowcoder.com/practice/832141cc566a49ad923bb9ad5bb80fac

枚举起点 + 带剪枝的 DFS

鉴于 较小,最直接且稳健的算法是:枚举树上的每一个节点作为路径起点,通过深度优先搜索(DFS)向外延伸,寻找所有合法的终点。

全源遍历 (All-Source Traversal) + 状态传递

由于二进制数的计算依赖于节点的访问顺序(),从某个起点出发向叶子方向延伸时,当前数值的计算天然契合 DFS 的递归结构。

为什么不使用高级树算法?

  • 点分治 (Centroid Decomposition):通常用于处理大规模树路径问题()。虽然可行,但在 的情况下,其实现的复杂度和常数开销相比 的暴力搜索带来的收益微乎其微,反而增加了代码出错的风险。
  • 树形 DP:由于路径的值与方向强相关(高位在前),且合并两条路径()时需要处理位移和拼接,状态极其复杂,不易转移。

因此,枚举起点 + DFS 是当前约束下的最优解。

代码实现

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

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

    int n;
    ll l, r;
    cin >> n >> l >> r;

    string w;
    cin >> w;

    vector<vector<int>> adj(n + 1);
    for (int i = 0; i < n - 1; i++) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    ll ans = 0;

    auto dfs = [&](auto&& self, int u, int p, ll cur_val) -> void {
        for (int v : adj[u]) {
            if (v == p)
                continue;
            ll next_val = cur_val * 2LL + (ll)w[v - 1] - '0';
            if (next_val > r)
                continue;
            if (next_val >= l)
                ans++;
            self(self, v, u, next_val);
        }
    };

    for (int i = 1; i <= n; i++) {
        dfs(dfs, i, -1, w[i - 1] - '0');
    }

    cout << ans << endl;
}
#AI时代的工作 VS 传统时代的工作,有哪些不同?#
每日一题@牛客网 文章被收录于专栏

牛客网每日一题

全部评论

相关推荐

2025-12-17 17:15
华东师范大学 运营
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务