This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
// #include <tr2/dynamic_bitset>
using namespace std;
// using namespace tr2;
#pragma GCC optimize("O3,unroll-loops,Ofast")
//#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
const long double eps = 1e-9;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int randgen(int left, int right) {
return uniform_int_distribution<int>(left, right)(rng);
}
long long randgenll(long long left, long long right) {
return uniform_int_distribution<long long>(left, right)(rng);
}
typedef long long ll;
typedef long double ld;
const int mod = 1e9 + 7;
struct Mint
{
int val;
Mint(int x = 0)
{
val = x % mod;
}
Mint(long long x)
{
val = x % mod;
}
Mint operator+(Mint oth)
{
return val + oth.val;
}
Mint operator*(Mint oth)
{
return 1LL * val * oth.val;
}
Mint operator-(Mint oth)
{
return val - oth.val + mod;
}
Mint fp(Mint a, long long n){
Mint p = 1;
while(n){
if(n & 1){
p = p * a;
}
a = a * a;
n /= 2;
}
return p;
}
Mint operator/(Mint oth){
Mint invers = fp(oth, mod - 2);
return 1LL * val * invers.val;
}
friend ostream& operator << (ostream& os, const Mint& lol){
os << lol.val;
return os;
}
};
struct AINT{
vector<pair<ll,Mint>> aint;
vector<pair<ll,Mint>> lazy;
pair<ll,Mint> b;
AINT(int n){
b = {1e18,Mint(0)};
aint.assign(n * 4 + 1,make_pair(1e18,Mint(0)));
lazy.assign(n * 4 + 1, make_pair(1e18, Mint(0)));
}
void update(int v, int tl, int tr, int l, int r, pair<ll,Mint> val){
if(lazy[v].first != 1e18){
if(aint[v].first == lazy[v].first){
aint[v].second = aint[v].second + lazy[v].second;
}else if(aint[v].first > lazy[v].first) aint[v] = lazy[v];
if(tl != tr){
if(lazy[v * 2].first == lazy[v].first){
lazy[v * 2].second = lazy[v * 2].second + lazy[v].second;
}else if(lazy[v * 2].first > lazy[v].first) lazy[v * 2] = lazy[v];
if(lazy[v * 2 + 1].first == lazy[v].first){
lazy[v * 2 + 1].second = lazy[v * 2 + 1].second + lazy[v].second;
}else if(lazy[v * 2 + 1].first > lazy[v].first){
lazy[v * 2 + 1] = lazy[v];
}
}
lazy[v] = b;
}
if(l <= tl && r >= tr){
if(aint[v].first == val.first){
aint[v].second = aint[v].second + val.second;
}else if(aint[v].first > val.first){
aint[v] = val;
}
if(tl != tr){
if(lazy[v * 2].first == val.first){
lazy[v * 2].second = lazy[v * 2].second + val.second;
}else if(lazy[v * 2].first > val.first){
lazy[v * 2] = val;
}
if(lazy[v * 2 + 1].first == val.first){
lazy[v * 2 + 1].second = lazy[v * 2 + 1].second + val.second;
}else if(lazy[v * 2 + 1].first > val.first){
lazy[v * 2 + 1] = val;
}
}
return;
}
if(l > tr || r < tl) return;
int tm = (tl + tr) / 2;
update(v * 2, tl, tm, l,r , val);
update(v * 2 + 1, tm + 1, tr, l, r, val);
if(aint[v * 2].first == aint[v * 2 + 1].first){
aint[v] = aint[v * 2];
aint[v].second = aint[v].second + aint[v * 2 + 1].second;
}else{
if(aint[v * 2].first < aint[v * 2 + 1].first) aint[v] = aint[v * 2];
else aint[v] = aint[v * 2 + 1];
}
}
pair<ll,Mint> query(int v, int tl, int tr, int l, int r){
if(lazy[v].first != 1e18){
if(aint[v].first == lazy[v].first){
aint[v].second = aint[v].second + lazy[v].second;
}else if(aint[v].first > lazy[v].first) aint[v] = lazy[v];
if(tl != tr){
if(lazy[v * 2].first == lazy[v].first){
lazy[v * 2].second = lazy[v * 2].second + lazy[v].second;
}else if(lazy[v * 2].first > lazy[v].first) lazy[v * 2] = lazy[v];
if(lazy[v * 2 + 1].first == lazy[v].first){
lazy[v * 2 + 1].second = lazy[v * 2 + 1].second + lazy[v].second;
}else if(lazy[v * 2 + 1].first > lazy[v].first){
lazy[v * 2 + 1] = lazy[v];
}
}
lazy[v] = b;
}
if(l <= tl && r >= tr) return aint[v];
if(l > tr || r < tl) return make_pair(1e18,Mint(0));
int tm = (tl + tr) / 2;
pair<ll,Mint> p1 = query(v * 2, tl ,tm, l, r);
pair<ll,Mint> p2 = query(v * 2 + 1, tm + 1, tr, l,r);
if(p1.first == p2.first){
p1.second = p1.second + p2.second;
return p1;
}else if(p1.first < p2.first) return p1;
return p2;
// int tm = (tl + tr) / 2;
// if(l <= tl && r >= tr) return aint[v];
// if(l > tr || r < tl) return 0;
// return max(query(v * 2, tl, tm,l,r), query(v * 2 + 1, tm + 1, tr, l,r));
}
};
struct AIB{
vector<int> aib;
AIB(int n){
aib.assign(n + 1,0);
}
void update(int pos, int val){
for(; pos < aib.size(); pos += (pos & -pos)){
aib[pos] += val;
}
}
int query(int pos){
int pl = 0;
for(; pos > 0; pos -= (pos & -pos)) pl += aib[pos];
return pl;
}
};
int red = 0;
int ______________________________________________________________________________________________________________________________________________;
void solve(){
int n, d;
cin >> n >> d;
vector<vector<int>> liste(n + 1);
vector<deque<int>> dp(n + 1),maxp(n + 1);
for(int i = 2; i <= n; i++){
int x;
cin >> x;
x++;
liste[i].push_back(x);
liste[x].push_back(i);
}
int ans = 0;
function<void(int,int)> dfs = [&](int nod, int p){
int maxim = 0, nd = 0;
for(auto i : liste[nod]){
if(i == p) continue;
dfs(i,nod);
if(maxim < dp[i].size()){
maxim = dp[i].size();
nd = i;
}
}
if(liste[nod].size() == 1 && nod != 1){
dp[nod].push_back(1);
maxp[nod].push_back(1);
return;
}
int crt = max(1, 1 + (dp[nd].size() <= d - 1 ? 0 : maxp[nd][d - 1]));
swap(dp[nod],dp[nd]);
swap(maxp[nd],maxp[nod]);
dp[nod].push_front(crt);
int lvl = maxp[nod][0];
maxp[nod].push_front(max(crt,lvl));
for(auto i : liste[nod]){
if(i == p || i == nd) continue;
int crt = max(1, 1 + (dp[i].size() <= d - 1 ? 0 : maxp[i][d - 1]));
dp[i].push_front(crt);
int lvl = maxp[i][0];
maxp[i].push_front(max(crt,lvl));
// if(nod == 1 && i == 3){
// for(auto j : dp[i]){
// cout << j << " ";
// }
// }
for(int j = 0; j < dp[i].size(); j++){
int pos = max(j, d - j);
int val1 = dp[i][j] + (dp[nod].size() <= pos ? 0 : maxp[nod][pos]);
int val2 = dp[nod][j] + (dp[i].size() <= pos ? 0 : maxp[i][pos]);
// if(nod == 1 && i == 3 && j == 1){
// cout << val1 << " " << val2;
// //cout << maxp[nod].size();
// }
dp[nod][j] = max({dp[nod][j],val1,val2});
}
for(int j = dp[i].size() - 1; j >= 0; j--){
if(j + 1 < dp[nod].size()){
maxp[nod][j] = max(dp[nod][j], maxp[nod][j + 1]);
}
}
}
ans = max(ans, maxp[nod][0]);
};
dfs(1,1);
cout << ans;
}
int32_t main(){
cin.tie(0)->sync_with_stdio(0);
int t = 1;
if(red) cin >> t;
while(t--){
solve();
}
}
/*
4 1
0 0 1
j + 1 + p >= d
p >= d - j - 1
i + j >= d
j >= d - i;
*/
Compilation message (stderr)
catinatree.cpp: In member function 'void AIB::update(int, int)':
catinatree.cpp:176:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
176 | for(; pos < aib.size(); pos += (pos & -pos)){
| ~~~~^~~~~~~~~~~~
catinatree.cpp: In lambda function:
catinatree.cpp:211:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::deque<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
211 | if(maxim < dp[i].size()){
| ~~~~~~^~~~~~~~~~~~~~
catinatree.cpp:223:45: warning: comparison of integer expressions of different signedness: 'std::deque<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
223 | int crt = max(1, 1 + (dp[nd].size() <= d - 1 ? 0 : maxp[nd][d - 1]));
| ~~~~~~~~~~~~~~^~~~~~~~
catinatree.cpp:235:48: warning: comparison of integer expressions of different signedness: 'std::deque<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
235 | int crt = max(1, 1 + (dp[i].size() <= d - 1 ? 0 : maxp[i][d - 1]));
| ~~~~~~~~~~~~~^~~~~~~~
catinatree.cpp:244:30: warning: comparison of integer expressions of different signedness: 'int' and 'std::deque<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
244 | for(int j = 0; j < dp[i].size(); j++){
| ~~^~~~~~~~~~~~~~
catinatree.cpp:246:55: warning: comparison of integer expressions of different signedness: 'std::deque<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
246 | int val1 = dp[i][j] + (dp[nod].size() <= pos ? 0 : maxp[nod][pos]);
| ~~~~~~~~~~~~~~~^~~~~~
catinatree.cpp:247:55: warning: comparison of integer expressions of different signedness: 'std::deque<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
247 | int val2 = dp[nod][j] + (dp[i].size() <= pos ? 0 : maxp[i][pos]);
| ~~~~~~~~~~~~~^~~~~~
catinatree.cpp:256:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::deque<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
256 | if(j + 1 < dp[nod].size()){
| ~~~~~~^~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |