列表

详情


NC256067. 游游的二进制树

描述

游游拿到了一棵树,共有n个节点,每个节点都有一个权值:0或者1。这样,每条路径就代表了一个二进制数。
游游想知道,有多少条路径代表的二进制数在[l,r]区间范围内?
(请注意:路径长度至少为1,例如,节点3到节点3虽然有一个权值,但并不是合法路径!)

输入描述

第一行输入三个正整数n,l,r,用空格隔开。
第二行输入一个长度为n的01串,第i个字符代表i号节点的权值。
接下来的n-1行,每行输入两个正整数uv,代表u号节点和v号节点有一条边连接。
1\leq n \leq 10^3
1\leq u,v \leq n
1\leq l \leq r \leq 10^{14}

输出描述

一个整数,代表合法的路径条数。

示例1

输入:

4 4 5
1010
1 2
2 3
3 4

输出:

3

说明:

路径1-2-3代表的二进制数为5。
路径3-2-1代表的二进制数为5。
路径4-3-2-1代表的二进制数为5。

示例2

输入:

3 1 2
100
1 2
1 3

输出:

6

说明:

任意合法路径均在区间[l,r]内。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Java 解法, 执行用时: 387ms, 内存消耗: 22708K, 提交时间: 2023-08-12 12:59:51

import java.util.*;

public class Main {

    static List<Integer>[] g;
    static long l;
    static long r;
    static int n;
    static String str;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        l = sc.nextLong();
        r = sc.nextLong();
        str = sc.next();
        g = new List[n + 1];
        Arrays.setAll(g, v -> new ArrayList<>());
        for (int i = 0; i < n - 1; i++) {
            int x = sc.nextInt();
            int y = sc.nextInt();
            g[x].add(y);
            g[y].add(x);
        }
        long ans = 0;
        for (int i = 1; i <= n; i++) {
            ans += dfs(i, -1, 0);
        }
        System.out.println(ans);
    }

    public static long dfs(int cur, int fa, long num) {
        if (num > r) return 0;
        long ans = 0;
        num = num << 1 | (str.charAt(cur - 1) - '0');
        if (fa != -1 && num >= l && num <= r) ans++;
        for (Integer next : g[cur]) {
            if (next != fa) {
                ans += dfs(next, cur, num);
            }
        }
        return ans;
    }
}

Go 解法, 执行用时: 14ms, 内存消耗: 1044K, 提交时间: 2023-08-12 12:59:15

package main

import (
	"bufio"
	. "fmt"
	"os"
)

func main() {
	in, out := bufio.NewReader(os.Stdin), bufio.NewWriter(os.Stdout)
	var n, l,r,ans int
	var s string
	var x, y int
	Fscan(in, &n, &l, &r, &s)
	g := make([][]int, n+1)
	for i := 0; i < n-1; i++ {
		Fscan(in, &x, &y)
		g[x] = append(g[x], y)
		g[y] = append(g[y], x)
	}

	var dfs func(int, int,int)
	dfs = func(x int, pre int, ret int) {
		
		for _, nxt := range g[x] {
			if nxt !=pre  {
                ret:=ret*2+int(s[nxt-1]-'0')
				if ret >= l && ret <= r {
					ans++
				} else if ret > r {
					return
				}
				dfs(nxt, x, ret)
			}
		}
	}
	for i := 1; i <= n; i++ {
		dfs(i, 0, int(s[i-1]-'0'))
	}
	Fprintln(out, ans)
	defer out.Flush()
}

C++ 解法, 执行用时: 15ms, 内存消耗: 5168K, 提交时间: 2023-08-12 12:58:49

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
vector<long long>h[N];
string s;
long long n,l,r,ans;

void dfs(int u,int fa,long long mid){
	mid=mid*2+s[u-1]-'0';
	if(mid>r)return;
	if(fa&&mid>=l)ans++;
	for(int v:h[u]){
		if(fa==v)continue;
		dfs(v,u,mid);
	}
}

int main(){
	cin>>n>>l>>r>>s;
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		h[x].push_back(y);
		h[y].push_back(x);
	}
	for(int i=1;i<=n;i++)
	dfs(i,0,0);
	cout<<ans<<endl;
	return 0;
}

Python3 解法, 执行用时: 1760ms, 内存消耗: 5684K, 提交时间: 2023-08-12 12:58:29

n,l , r =map(int, input().split())
s = input()
g = [[] for _ in range(n + 10)]
for i in range(n - 1):
    u, v = map(int,input().split())
    g[u].append(v)
    g[v].append(u)

res = 0
st = [False] * (n + 1)
def dfs(u, now):
    global res
    st[u] = True
    now += s[u - 1]
    if len(now) > 1 and l <= int(now,2) <= r:
        
        res += 1
    for p in g[u]:
        if not st[p]:
            dfs(p, now)
    
    
for i in range(n + 1):
    st = [False] * (n + 1)
    dfs(i, '')
print(res)

上一题