注意到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();
}

京公网安备 11010502036488号