# Neko and tree HDU - 6540 (tree dp)

Give you a tree. There are some important points on the tree. Let you choose a point set that only contains important points. The farthest two points in the point set are not more than k. how many choices are there

After thinking for a long time, the explanation is too brief...

dp[i][j] represents the number of schemes with the farthest distance k from point I in this subtree.

Considering how to transfer from the subtree, obviously when we traverse to a new subtree, we need to multiply all previous schemes by the scheme of this subtree to update.

That is DP [u] [max (I, j + 1] + = dp[u][i]*dp[to][j]

The complexity of violence update is k^2. It needs to be prefixed and maintained,

Finally, if this point is optional, you can choose this point or not, multiply by 2, and then add this point only.

In the final calculation of the sum, if this point is not the root, only the case with the length of k will be added, because other cases may be updated, and it will be calculated in his ancestry, if not all schemes will be added.

```#include <bits/stdc++.h>

using namespace std;
#define N 5010
#define ll long long
#define mod 1000000007
#define go(i,a,b) for(int i=(a);i<=(b);i++)
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
ll dp[N][N],sum[N][N],f[N],ans;
vector<int>path[N];
int is[N];
int n,m,k,x,y;
void cal(int u,int to){
go(i,1,k-1)f[i]=dp[u][i]*sum[to][min(i,k-i)-1]%mod;
go(i,1,k/2)add(f[i],(mod-dp[u][i]*dp[to][i-1]%mod)%mod);//Tolerance and exclusion, subtraction of repeated calculation
go(i,1,k)
add(dp[u][i],(dp[to][i-1]+f[i])%mod),//Plus the scheme of this subtree
sum[u][i]=(sum[u][i-1]+dp[u][i])%mod;
}
void dfs(int u,int fa){
for(auto to:path[u]){
if(to==fa)continue;
dfs(to,u);
cal(u,to);
}
if(is[u]){//If this point is optional
sum[u]=dp[u]=1;//Just choose this point
go(i,1,k)
add(dp[u][i],dp[u][i]),//Sorting it doesn't choose two kinds, so multiply by 2
sum[u][i]=(sum[u][i-1]+dp[u][i])%mod;//Update prefix and
}
}
int main()
{

n=m=k=5000;
go(i,2,n)
path[i].push_back(i-1),
path[i-1].push_back(i);
go(i,1,n)is[i]=1;
dfs(1,0);
cout<<ans<<endl;
return 0;
}
```

Added by aquaman1856 on Tue, 05 Nov 2019 18:34:46 +0200