Title effect: There are a \ (n-\) tree points, each point you give assign a \ ([1, m] \ ) integer values within the weight, so that two adjacent right-point value a difference of at least \ (k \) , ask a few programs.
\ (n, k \ leq 100 , m \ leq 10 ^ 9 \)
Solution
Set \ (f [i] [j ] \) represents \ (I \) subtree rooted satisfies a condition, and \ (I \) weight value \ (J \) of the program number, and transfer with prefix optimization .
Can be found by playing table \ (f [i] [j ] \) is symmetrical, ie \ (F [I] [J] = F [I] [m-J +. 1] \) , and left up to \ ((n-1) * k \) different numbers, the middle section is the same. So we recorded before \ ((n-1) * k \) states, and \ (pos [i] \) represents a start from which are identical, will be able to \ (O (1) \) is determined and the prefix.
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=107,M=10017;
const ll P=1000000007;
int T,n,m,k;
ll f[N][M],s[N][M],pos[N];
int tot,st[N],to[N<<1],nx[N<<1];
void add(int u,int v){to[++tot]=v,nx[tot]=st[u],st[u]=tot;}
ll sum(int u,int j){
ll ret=0;
if(j<=10010)return s[u][j];
else if(j<pos[u])return s[u][j];
else{
ret=(ret+s[u][pos[u]-1])%P;
if(j<=m-pos[u]+1)ret=(ret+f[u][pos[u]]*(j-pos[u]+1)%P)%P;
else{
ret=(ret+f[u][pos[u]]*(m-2*pos[u]+2)%P)%P;
ret=(ret+s[u][pos[u]-1]-s[u][m-j]+P)%P;
}
return ret;
}
}
void dfs(int u,int from){
for(int i=st[u];i;i=nx[i])if(to[i]!=from)dfs(to[i],u);
for(int j=1;j<=10010&&j<=m;++j){
f[u][j]=1;
for(int i=st[u];i;i=nx[i])if(to[i]!=from){
if(k==0)f[u][j]=f[u][j]*sum(to[i],m)%P;
else{
ll tmp=0;
if(j-k>0)tmp=(tmp+sum(to[i],j-k))%P;
if(j+k<=m)tmp=(tmp+sum(to[i],m)-sum(to[i],j+k-1)+P)%P;
f[u][j]=f[u][j]*tmp%P;
}
}
}
for(int j=1;j<=10010&&j<=m;++j)if(f[u][j]==f[u][j+1]){pos[u]=j;break;}
for(int j=1;j<=10010&&j<=m;++j)s[u][j]=(s[u][j-1]+f[u][j])%P;
}
int main(){
freopen("label.in","r",stdin);
//freopen("label.out","w",stdout);
scanf("%d",&T);
while(T--){
tot=0;
memset(st,0,sizeof(st));
memset(f,0,sizeof(f));
memset(s,0,sizeof(s));
memset(pos,0,sizeof(pos));
memset(to,0,sizeof(to));
memset(nx,0,sizeof(nx));
scanf("%d%d%d",&n,&m,&k);
for(int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);
dfs(1,0);
printf("%lld\n",sum(1,m));
}
return 0;
}