### AghaTizi's blog

By AghaTizi, 4 years ago,

This blog is about problem 3 from this blog.

Given a tree T of N nodes and an integer K, find number of different sub trees of size less than or equal to K.

This is a very useful problem in the whole world of cp. The solution given in that blog is O(n * K2) but we want to change it to O(n * K).

Consider Subv as the size of the subtree of vertex v.

The solution is similar to the given solution in that blog and the difference is very simple. You don't have to iterate over all K values. It's obvious that if i > Subv then dp[v][i] = 0. So each time you have to iterate over min(K, Subv) values.

The code becomes like this.

The Code

#### The Proof Of The Complexity

First we introduce the array EnterTime. If EnterTimev = x then v is the x'th vertex we have entered to solve. Every vertex has a stv which is an array and in the very beginning stv = {v} for all v. We'll change this set later and I'll explain how. Also consider stv always sorted by EnterTime.

We want to build a digraph H of size n. When we're about to update dp[v] from its child u, add a directed edge from every vertex is stu to every vertex in stv in the digraph H.

Then update stv by adding the first K - size(stv) vertices from stu. (If size(stv) = k then ignore this) Also erase every vertex from stu.

The complexity is equal to number of edges of H. We want to prove that number of edges in H is at most n * (2 * K) by proving that every vertex in H has at most 2 * K edges going out from it.

By our definition at any time, for any vertex v there's at most 1 vertex u such that v is in stu. Consider some w's last set is stu and we're about to update dp[v] from its child u. Consider w being in the p'th position in stu. By our definition edges that go out of w are edges to the first p - 1 vertices in stu.

We know that p ≤ K so until now, edges going out from w are at most K. When we're updating dp[v] we'll add at most K to that number. So by far w has at most 2 * K edges going out from it. Also we've considered stu to be the last set that w is in. Hence there won't be any other edges going out from w in the future.

So we have proved number of edges in H is at most n * (2 * K) so the complexity is O(n * K).

• +110

 » 3 years ago, # | ← Rev. 5 →   0 I am not able to get the desired output for the problem on no. of k-subtrees Can anyone tell what is wrong with my code using AghaTizi idea ? Spoiler#include using namespace std; #define pb push_back #define m_p make_pair #define rep(i,a,b) for(int i=a;i , prefix_sum(a,a+n) , reverse(a,a+n) , priority_queue max heap , priority_queue , greater > min heap; // == precedence gretaer then & ll n,m,k; string s; vector vec[200005]; ll arr[200005]; priority_queue pq; ll mp[200005]; ll dp[1001][51];//n k ll vis[1001]; ll sub[1001]; void dfs(int a){ sub[a]=1; vis[a] = 1; dp[a][0] = 1; dp[a][1] = 1; for(auto it:vec[a]){ if(!vis[it]){ dfs(it); vector tmp(k+1,0); for(int i=1;i<=min(sub[a],k);i++){ for(int j = 0; j<=sub[it] && i+j<=k;j++){ tmp[i+j] += dp[a][i]*dp[it][j]; } } sub[a]+=sub[it]; for(int i=0;i<=min(sub[a],k);i++){ dp[a][i] = tmp[i]; } } } } int main() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); ll a1,a2,k1,k2,i,j,c=0,t,z,x=0,y=0,cnt=0,f=1,maxi=-1; cin>>n>>k; rep(i,0,n-1){ cin>>x>>y; vec[x].pb(y); vec[y].pb(x); } dfs(1); cout<
•  » » 23 months ago, # ^ |   0 Hey can you share link of the problem.
•  » » » 14 months ago, # ^ |   -26 https://codeforces.com/blog/entry/20935 here is it, inside this blog
 » 16 months ago, # |   -23 good job