注意到n<=1e3,对于一个无根树,令每一个点为根,然后分别做搜索(我采用BFS)。复杂度O(n^2)很合理。

然后做BFS搜索,把当前结点与当前值扔到队列里面。如果访问到点为1,乘2加1(<<1|1);如果访问到点为0,乘2(<<1).

但是交了一发竟然没过,哦!原来溢出了,做一个防溢出处理即可。

using namespace std;
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define PII pair<int,int>
#define PLL pair<ll,ll>
void solve(){
    int n;
    cin>>n;
    ll l,r;
    cin>>l>>r;
    string s;
    cin>>s;
    s=' '+s;
    vector<vector<int>>tr(n+1,vector<int>());
    for(int i=0;i<n-1;i++){
        int u,v;
        cin>>u>>v;
        tr[u].push_back(v);
        tr[v].push_back(u);
    }
    ll ans=0;
    for(int root=1;root<=n;root++){
        vector<int>vis(n+1,0);
        vis[root]=1;
        queue<PLL>q;    //point,val
        ll cur=(s[root]=='1');
        q.push({root,cur});
        while(!q.empty()){
            int e=q.front().first;
            ll val=q.front().second;
            if(val>=1e15)val=1e15;  //防止溢出
            if(e!=root&&val>=l&&val<=r)ans++;
            q.pop();
            for(auto x:tr[e]){
                if(vis[x])continue;
                vis[x]=1;
                if(s[x]=='1')q.push({x,val<<1|1});
                else q.push({x,val<<1});
            }
        }
    }
    cout<<ans<<endl;
}
int main(){
	int T=1;
	// cin>>T;
	while(T--)
	solve();
}