题目:
分析:
其实直接用差
<
=
k
<=k
<=k的减去差
<
k
<k
<k的就是等于
k
k
k的答案。
然后枚举一个点为最大值,然后只往小编号扩张就好了(避免重复)
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#include<deque>
#include<set>
#define LL long long
#define ch cheap
#define XJQ (int)19260817
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
int x[3338];
struct node{
int to,next;
}e[8000];
int ls[8000],cnt=0;
int dfs(int now,int f,int root,int k)
{
LL sum=1;
for(int i=ls[now];~i;i=e[i].next)
if(f!=e[i].to&&x[root]>=x[e[i].to]&&x[root]-x[e[i].to]<=k&&(root<e[i].to||x[root]!=x[e[i].to]))
sum=(sum*(dfs(e[i].to,now,root,k)+1))%XJQ;
return sum%XJQ;
}
int main()
{
memset(ls,-1,sizeof(ls));
int n=read(),k=read();
for(int i=1;i<=n;i++) x[i]=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read();
e[cnt]=(node){y,ls[x]};ls[x]=cnt++;
e[cnt]=(node){x,ls[y]};ls[y]=cnt++;
}
LL ans1=0,ans2=0;
for(int i=1;i<=n;i++)
{
(ans1+=dfs(i,0,i,k))%=XJQ;
if(k) (ans2+=dfs(i,0,i,k-1))%=XJQ;
}
cout<<(ans1-ans2+XJQ)%XJQ;
return 0;
}