版权声明:转载无所谓的。。。 https://blog.csdn.net/xuxiayang/article/details/83545016
大意
求树上联通快中最大值与最小值之差为 的方案数
思路
设最大值与最小值之差为
正好为 的方案数 的方案数- 的方案数
于是我们就可以树形 啦
大意
#include<cstdio>
#define mod 19260817
using namespace std;
typedef long long LL;int l[3501],n,k,tot,v[3501];
struct node{int next,to;}e[7001];
inline void add(register int u,register int v){e[++tot]=(node){l[u],v};l[u]=tot;return;}
LL ans;
inline LL dp(register int x,register int fa,register int mx)
{
long long ass=1;
for(register int i=l[x];i;i=e[i].next)
if(v[mx]>=v[e[i].to]&&v[mx]-v[e[i].to]<=k&&e[i].to!=fa&&(v[e[i].to]!=v[mx]||e[i].to>mx))//必须满足限制并且不往走,同时处理同组解的情况
(ass*=dp(e[i].to,x,mx)+1)%=mod;//计算
return ass;//返回
}
signed main()
{
scanf("%d%d",&n,&k);
for(register int i=1;i<=n;i++) scanf("%d",v+i);//输入
for(register int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);//输入
for(register int i=1;i<=n;i++) (ans+=dp(i,0,i))%=mod;//计算
if(k==0) return printf("%lld",ans%mod)&0;//特判
k--;//计算k-1
for(register int i=1;i<=n;i++) (ans=ans-dp(i,0,i)+mod)%=mod;//计算
printf("%lld",ans);//输出
}