标签:input put alt div 一个 ace 最小值 gif 问题
分析
我们把差值小于等于k的方案数和插值小于k的方案数相减就是等于k的方案数嘛
然后我们每次对以i为根的子树求方案数,但是有问题:如果值相等,可能会算多次,所以我们只算比编号根大的点,就避免了重复。
#include <iostream> #include <cstdio> using namespace std; const int N=3333+10; const int P=19260817; struct Edge { int u,v,nx; }g[2*N]; int cnt,list[N]; int w[N]; int n,k; void Add(int u,int v) { g[++cnt].u=u;g[cnt].v=v;g[cnt].nx=list[u];list[u]=cnt; } int Dfs(int u,int fa,int mxid) { long long ans=1; for (int i=list[u];i;i=g[i].nx) if (g[i].v!=fa&&w[mxid]>=w[g[i].v]&&w[mxid]-w[g[i].v]<=k&&(mxid<g[i].v||w[mxid]!=w[g[i].v])) (ans*=1ll*Dfs(g[i].v,u,mxid)+1)%=P; return ans; } int main() { freopen("lkf.in","r",stdin); freopen("lkf.out","w",stdout); scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) scanf("%d",&w[i]); for (int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); Add(u,v);Add(v,u); } int smaller_or_equals_k=0,smaller_or_equals_k_1=0; for (int i=1;i<=n;i++) (smaller_or_equals_k+=Dfs(i,-1,i))%=P; if (k) { k--; for (int i=1;i<=n;i++) (smaller_or_equals_k_1+=Dfs(i,-1,i))%=P; } printf("%d",(smaller_or_equals_k-smaller_or_equals_k_1+P)%P); }
标签:input put alt div 一个 ace 最小值 gif 问题
原文地址:https://www.cnblogs.com/mastervan/p/9818598.html