QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#348854 | #8134. LCA Counting | ucup-team228# | WA | 2ms | 9288kb | C++20 | 4.9kb | 2024-03-09 21:50:53 | 2024-03-09 21:50:53 |
Judging History
answer
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("avx2") // doesn't work on Yandex
//#pragma GCC target("avx") // for old judges
//#pragma GCC target("bmi,bmi2,lzcnt,popcnt") // fast bit operations
#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <deque>
#include <cmath>
#include <algorithm>
#include <cassert>
#include <chrono>
#include <random>
#include <string>
#include <numeric>
#include <complex>
#include <tuple>
#include <utility>
#include <bitset>
#include <array>
#include <stack>
#include <sstream>
#include <unordered_set>
using namespace std;
typedef long long ll;
string to_string(string a) { return '"' + a + '"'; }
string to_string(char a) { return "'" + string(1, a) + "'"; }
string to_string(const char* a) { return to_string((string) a); }
string to_string(bool a) { return a ? "true" : "false"; }
template <class T1, class T2>
string to_string(pair<T1, T2> a) {
return "(" + to_string(a.first) + ", " + to_string(a.second) + ")";
}
template <class T>
string to_string(T a) {
bool first = true; string res = "{";
for (const auto& i : a) {
if (!first) res += ", ";
first = false;
res += to_string(i);
}
res += "}";
return res;
}
void debug_out() { cerr << endl; }
template <class T1, class... T2>
void debug_out(T1 a, T2... b) {
cerr << " " << to_string(a);
debug_out(b...);
}
#ifdef LOCAL
#define out(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define out(...) 42
#endif
clock_t start_time; void start_timer() { start_time = clock(); }
double get_time() { return (double) (clock() - start_time) / CLOCKS_PER_SEC; }
void Solve();
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
#ifdef LOCAL
freopen("usr/share/man/man1/input.txt", "r", stdin);
#endif
start_timer();
Solve();
#ifdef LOCAL
cerr << fixed << setprecision(3);
cerr << endl << "Time spent: " << get_time() << endl;
#endif
return 0;
}
// do something, stay focused
// look for stupid bugs
// guess, slow, stress
// don't overgeneralize
// don't rush
// don't waste time on standings
// SOLVE THE PROBLEM OR DIE TRYING
// THE SOLUTION IS ALWAYS SIMPLE
// THE CODE IS ALWAYS SHORT
const int N = 2e5 + 5;
const int L = 20;
vector<int> g[N];
int tin[N];
int tout[N];
int up[N][L];
int timer = 1;
void dfs_lca(int v = 1, int p = 1) {
tin[v] = timer++;
up[v][0] = p;
for (int i = 1; i < L; i++) {
up[v][i] = up[up[v][i - 1]][i - 1];
}
for (int u : g[v]) {
if (u != p) dfs_lca(u, v);
}
tout[v] = timer - 1;
}
bool is_anc(int u, int v) {
return tin[u] <= tin[v] && tin[v] <= tout[u];
}
int lca(int u, int v) {
if (is_anc(u, v)) return u;
if (is_anc(v, u)) return v;
for (int i = L - 1; i >= 0; i--) {
if (!is_anc(up[u][i], v)) u = up[u][i];
}
return up[u][0];
}
void add_e(int u, int v) {
g[u].push_back(v);
g[v].push_back(u);
}
int dp[N];
vector<int> all;
set<int> tree;
set<int> ls;
void dfs(int v = 1, int p = 0) {
if (v > 1 && g[v].size() == 1) {
g[v].clear();
dp[v] = 1;
return;
}
vector<pair<int, int>> cur;
for (int u : g[v]) {
if (u == p) continue;
dfs(u, v);
cur.push_back({dp[u], u});
}
sort(cur.rbegin(), cur.rend());
g[v].clear();
for (auto [d, u] : cur) {
g[v].push_back(u);
}
dp[v] = 1;
for (int i = 0; i <= 1; i++) {
if (i < cur.size()) {
dp[v] += cur[i].first;
}
}
}
void dfs_all(int v = 1, int p = 0) {
if (g[v].empty()) {
all.push_back(v);
}
for (int u : g[v]) {
dfs_all(u, v);
}
}
struct E {
int mx = -1;
int cnt;
};
bool operator<(const E& a, const E& b) {
return std::tie(a.mx, a.cnt) < std::tie(b.mx, b.cnt);
}
E f[N];
void dfs_f(int v = 1, int p = 0) {
for (int i = 0; i < g[v].size(); i++) {
int u = g[v][i];
if (i > f[u].mx) {
f[u] = {i, 1};
}
else if (i == f[u].mx) {
f[u].cnt++;
}
dfs_f(u, v);
}
}
void Solve() {
int n;
cin >> n;
for (int i = 2; i <= n; i++) {
int p;
cin >> p;
add_e(i, p);
}
dfs();
dfs_all();
dfs_f();
dfs_lca();
sort(all.begin(), all.end(), [&](int i, int j) {
return f[i] < f[j];
});
for (int l : all) {
auto it = ls.lower_bound(l);
if (it != ls.end()) {
tree.insert(lca(l, *it));
}
if (it != ls.begin()) {
--it;
tree.insert(lca(l, *it));
}
tree.insert(l);
ls.insert(l);
cout << tree.size() << " ";
}
cout << "\n";
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 8644kb
input:
7 1 1 2 4 2 2
output:
1 3 5 6
result:
ok 4 number(s): "1 3 5 6"
Test #2:
score: 0
Accepted
time: 2ms
memory: 8920kb
input:
10 1 1 2 2 1 1 1 2 4
output:
1 3 5 6 7 8 9
result:
ok 7 numbers
Test #3:
score: 0
Accepted
time: 2ms
memory: 9288kb
input:
10 1 2 2 4 5 6 1 2 4
output:
1 3 5 7 8
result:
ok 5 number(s): "1 3 5 7 8"
Test #4:
score: 0
Accepted
time: 2ms
memory: 8164kb
input:
10 1 2 3 3 3 5 6 4 9
output:
1 3 4
result:
ok 3 number(s): "1 3 4"
Test #5:
score: -100
Wrong Answer
time: 0ms
memory: 8564kb
input:
1000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 4 1 2 2 1 1 1 1 2 1 1 1 1 2 2 1 1 1 1 1 6 3 1 1 1 2 2 1 1 2 1 2 1 3 1 2 1 1 2 1 1 1 1 1 1 1 4 1 5 1 1 1 1 1 2 1 1 2 1 2 1 2 5 3 1 3 1 1 2 1 2 1 1 3 2 1 6 2 1 2 5 1 1 1 3 2 1 2 1 1 1 1 1...
output:
1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 59 60 61 63 64 65 66 67 68 69 70 71 72 74 75 76 77 78 79 80 81 82 83 84 85 86 88 89 90 91 93 94 95 97 98 99 100 101 102 103 104 105 106 107 108...
result:
wrong answer 3rd numbers differ - expected: '5', found: '4'