 # TREECLR - Editorial

Author: Sachin Deb
Testers: Harris Leung
Editorialist: Nishank Suresh

1898

# PREREQUISITES:

Depth-first search

# PROBLEM:

You are given a tree T and an integer C. Count the number of ways to color the vertices of T with colors 1, 2, \ldots, C such that no two vertices with a distance of \leq 2 have the same color.

# EXPLANATION:

First, root the tree at some node, say 1. Let us try to color the tree in top-down fashion, i.e, from the root down to the leaves.

Look at some vertex u. What restriction do we have on its possible choice of colors, in relation to vertices that have been colored already?

Let p be the parent of u, and let g be the parent of p. For now, assume p and g both exist.

p and g have been colored already, and so u cannot have the same color as either p or g. p and g must also have distinct colors, so we are left with C-2 choices.

Further, u also cannot have the same color as some other vertex v that is a child of p and has already been colored. Note that each such vertex will also have a distinct color.

So, suppose s children of p have been colored already. Then, there are C-s-2 choices for the color of u.

Note that when either p or g (or both) don’t exist, the number of choices becomes C-s-1 or C-s respectively: make sure to not forget those cases.

Once we know the number of choices for each vertex u, the final answer is simply their product.

Implementing this is relatively simple, and can be done with a single DFS. Checking whether p and g exist is straightforward, and computing s is also trivial since we know how many children of p we have processed already.

# TIME COMPLEXITY

\mathcal{O}(N) per test case.

# CODE:

Setter's code (C++)
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair <int, int> pii;

#define ALL(a) a.begin(), a.end()
#define FastIO ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define IN freopen("input.txt","r+",stdin)
#define OUT freopen("output.txt","w+",stdout)

#define DBG(a) cerr<< "line "<<__LINE__ <<" : "<< #a <<" --> "<<(a)<<endl
#define NL cerr<<endl

template < class T1,class T2>
ostream &operator <<(ostream &os,const pair < T1,T2 > &p)
{
os<<"{"<<p.first<<","<<p.second<<"}";
return os;
}

long long bigmod ( long long a, long long p, long long m )
{
long long res = 1;
long long x = a;

while ( p )
{
if ( p & 1 ) //p is odd
{
res = ( res * x ) % m;
}
x = ( x * x ) % m;
p = p >> 1;
}

return res;
}

const int N=1e6+1;
const ll oo=1e9+7;

vector<int> g[N];

ll fact[N];
ll inv_fact[N];

void init()
{
fact=1;
for(ll i=1;i<N;i++)
fact[i]=(fact[i-1]*i)%oo;
inv_fact[N-1] = bigmod(fact[N-1],oo-2,oo);
for(ll i=N-2;i>=0;i--)
inv_fact[i]=(inv_fact[i+1]*(i+1))%oo;
}

ll ncr(int n,int r)
{
if(r>n) return 0;
return fact[n]*inv_fact[r]%oo*inv_fact[n-r]%oo;
}

int n,c;
ll dfs(int u,int p)
{
int x = 0;
ll ret=1;
for(int v: g[u])
{
if(v==p) continue;
x++;
ret=(ret*dfs(v,u))%oo;
}
ret = (ret*ncr(c-2,x))%oo * fact[x] % oo;
return ret;
}

int32_t main()
{
FastIO;
cin>>n>>c;
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
init();
ll ans = c;
for(int v: g)
{
ans = ans * dfs(v,1)%oo;
}
ans = ans * ncr(c-1,g.size()) % oo * fact[g.size()] % oo;
cout<<ans<<"\n";
}

Tester's code (C++)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fi first
#define se second
const ll mod=1e9+7;
const int N=2e6+1;
ll n,k;
ll ans=1;
void dfs(int id,int p,int hp){
ans=ans*(k-hp)%mod;
int shp=1+(p!=0);
if(c==p) continue;
dfs(c,id,shp);
shp++;
}
}
void solve(){
cin >> n >> k;
for(int i=1; i<n ;i++){
int u,v;cin >> u >> v;
}
dfs(1,0,0);
cout << ans << '\n';
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
solve();
}

Editorialist's code (C++)
#include "bits/stdc++.h"
// #pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
using namespace std;
using ll = long long int;
mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());

int main()
{
ios::sync_with_stdio(false); cin.tie(0);

int n, c; cin >> n >> c;
for (int i = 0; i < n-1; ++i) {
int u, v; cin >> u >> v;
}

const int mod = 1e9 + 7;
int ans = c;

auto dfs = [&] (const auto &self, int u, int p) -> void {
int poss = c-2 + (u == 0);
for (int v : adj[u]) {
if (v == p) continue;
ans = (1LL * ans * poss)%mod;
--poss;
self(self, v, u);
}
};
dfs(dfs, 0, 0);
cout << ans << '\n';
}

3 Likes

Well done problem setter: Number of ways to paint a tree of N nodes with K distinct colors with given conditions - GeeksforGeeks.

20 Likes

He is a virat kohli fan, what did you expect?

6 Likes

My Bfs Approach : CodeChef

2 Likes

Totally same question E - Virus Tree 2

7 Likes

This was a co incidence…
I was the setter even the admins and the moderator found the problem unique. Actually its not possible to scan all the problems in the world to check if your idea already exists or not. We have other works too brother. So please solve problems rather than clicking websites for solutions.

4 Likes

No need of applying any dfs I guess : Solution.
Also this problem deserved more sample test cases yaar.

1 Like

https://www.codechef.com/viewsolution/72134557
Can anyone tell me what’s wrong in my approach ? I can’t figure it out.

People are leaving CodeChef because of people like you. you have just copy paste the question. this question is available on every platefrom like atcodre ,gfg hackerrank etc…
and you have other work then why you have set the problem of contest , go and do your own work.

7 Likes

Hello Setter, this was a very good problem , can u provide us more with this kind of problems ,
Thank u.

Wow, after copying the problem you are making excuses. And what is with that attitude no doubt you can’t set original problems, arrogant idiots like you are the reason top coders prefer other platforms over cc. Even problem setters are cheaters on codechef. Go do your other work.

3 Likes

Are you sure that the Setter’s code in the editorial is written by you ?

Because, I have checked some random past submissions in your profile and the general template you have been using (since over an year) is the following.

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;
using namespace std;
#define getbit(n, i) (((n) & (1LL << (i))) != 0)
#define setbit0(n, i) ((n) & (~(1LL << (i))))
#define setbit1(n, i) ((n) | (1LL << (i)))
#define togglebit(n, i) ((n) ^ (1LL << (i)))
#define lastone(n) ((n) & (-(n)))
char gap = 32;
#define ll long long
#define lll __int128_t
#define pb push_back
typedef tree<
int,
null_type,
less<int>,
rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;
ll hashPrime = 1610612741;


While the Setter’s code in the editorial have a different template than this. In my opinion, this seems fishy to me!
If this code is not written by you, then you must credit the original author.

Despite of the fact that you have copied the problem or not, you should sincerely apologize for the fault on your side, instead of being arrogant to others. Lots of people compete in these contests, and they put in so much efforts and time, while these kind of things just ruins it off, and also creates a bad impression on the platform.

7 Likes

This is my template…One of my senior has also solved the problem and I submitted that solution to match the output that I generated from my code…But somehow contests admin skipped my solution and took the later one…

Now brother stop accusing others, yes its my fault that I don’t have enough knowledge that a problem 100% unique or not…

you basically don’t know the background story and barking like a mad after getting bashed by the problem. So please have a sleep and if you find everyone cheater Just leave.

1 Like

Dude solve more problems rather being a noob and bark all the day saying cheater cheater…if your skill is not up to the mark then its not my duty to save your rating by checking all the problems in the world to find my idea unique.

Bhai maina bas ek google kia gfg mai milgya.
Atleast what the problem actually is asking for baas usko google karke check karlo 1 Like

Ihr Professionelle Schädlingsbekämpfung und Kammerjäger Kraus

Kammerjäger & Schädlingsbekämpfung Kraus in ihrer Nähe 01579 24 92 996 NRW Wir sind Ihr zertifizierter Verband aus NRW ! Preiswert Aachen

Kammerjäger & Schädlingsbekämpfungsschände, Lästlinge und Ungeziefer sind der Schrecken für jeden Mieter oder Besitzer eines Hauses. Es spielt dabei keine Rolle, ob der Ärger mit Ratten, eher harmlosen Silberfischen im Bad oder mit Tauben auf dem Dachboden besteht. Ungeziefer und andere Schädlinge im Haus, in der Wohnung beseitigt eine Schädlingsbekämpfung durch den Sterillion Kammerjäger Schädlingsbekämpfung ! Ungeziefer sind von keinem gerne gesehen und die Schädlinge können überall sein. Winzig kleine Wanzen, Wespen oder große Ratten. Unsere Sterillion Kammerjäger Aachen beseitigen diese Plagen. Wir versichern, dass alle Schädlinge aus Ihrem Heim oder Ihrem Geschäft verschwinden. Lassen Sie uns diesen Auftrag dies für Sie erledigen! Kammerjäger Aachen

Kammerjäger, Schädlingsbekämpfung, Ameisenbekämpfung, Bettwanzenbekämpfung, Wespenbekämpfung, Mückenbekämpfung, Mottenbekämpfung, Käferbekämpfung, Kakerlakenbekämpfung, Holzwurmbekämpfung, Mäusebekämpfung, Rattenbekämpfung, Marderbekämpfung, Zeckenabwehr, Ungezieferbekämpfung

Kammerjäger Kraus
01579/2492996
info@kammerjaeger-kraus.de