QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#65464 | #4839. Smaller LCA | YaoBIG | WA | 1134ms | 56760kb | C++17 | 6.6kb | 2022-12-01 09:33:29 | 2022-12-01 09:33:32 |
Judging History
answer
#include "bits/stdc++.h"
#define rep(i, a, n) for (auto i = a; i <= (n); ++i)
#define revrep(i, a, n) for (auto i = n; i >= (a); --i)
#define all(a) a.begin(), a.end()
#define sz(a) (int)(a).size()
template<class T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T &a, T b) { if (b < a) { a = b; return 1; } return 0; }
using namespace std;
template<class A, class B> string to_string(const pair<A, B> &p);
string to_string(const string &s) { return '"' + s + '"'; }
string to_string(const char *s) { return to_string((string) s); }
string to_string(char c) { return "'" + string(1, c) + "'"; }
string to_string(bool x) { return x ? "true" : "false"; }
template<class A> string to_string(const A &v) {
bool first = 1;
string res = "{";
for (const auto &x: v) {
if (!first) res += ", ";
first = 0;
res += to_string(x);
}
res += "}";
return res;
}
template<class A, class B> string to_string(const pair<A, B> &p) {
return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
void debug_out() { cerr << endl; }
template<class H, class... T> void debug_out(const H& h, const T&... t) {
cerr << " " << to_string(h);
debug_out(t...);
}
#ifndef ONLINE_JUDGE
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) if(0) puts("No effect.")
#endif
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vi>;
/**
* Author: Yuhao Yao
* Date: 22-10-25
* Description: Heavy Light Decomposition for a rooted tree $T$. The root is set as $0$ by default. It can be modified easily for forest.
* $g$ should be the adjacent list of the tree $T$.
* $chainApply(u, v, func, val)$ and $chainAsk(u, v, func)$ are used for apply / query on the simple path from $u$ to $v$ on tree $T$. $func$ is the function you want to use to apply / query on a interval. (Say rangeApply / rangeAsk of Segment tree.)
* Time: O(|T|) for building. O(\log |T|) for lca. O(\log |T| \cdot A) for chainApply / chainAsk, where $A$ is the running time of $func$ in chainApply / chainAsk.
* Status: tested on https://codeforces.com/contest/487/problem/E.
*/
struct HLD {
int n; /// start-hash
vi fa, hson, dfn, dep, top;
HLD(vector<vi> &g, int rt = 0): n(sz(g)), fa(n, -1), hson(n, -1), dfn(n), dep(n, 0), top(n) {
vi siz(n);
auto dfs = [&](auto &dfs, int now) -> void {
siz[now] = 1;
int mx = 0;
for (auto v: g[now]) if (v != fa[now]) {
dep[v] = dep[now] + 1;
fa[v] = now;
dfs(dfs, v);
siz[now] += siz[v];
if (mx < siz[v]) {
mx = siz[v];
hson[now] = v;
}
}
};
dfs(dfs, rt);
int cnt = 0;
auto getdfn = [&](auto &dfs, int now, int sp) {
top[now] = sp;
dfn[now] = cnt++;
if (hson[now] == -1) return;
dfs(dfs, hson[now], sp);
for (auto v: g[now]) {
if(v != hson[now] && v != fa[now]) dfs(dfs, v, v);
}
};
getdfn(getdfn, rt, rt);
} /// end-hash
int lca(int u, int v) { /// start-hash
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
u = fa[top[u]];
}
if (dep[u] < dep[v]) return u;
else return v;
} /// end-hash
template<class... T> /// start-hash
void chainApply(int u, int v, const function<void(int, int, T...)> &func, const T&... val) {
int f1 = top[u], f2 = top[v];
while (f1 != f2) {
if (dep[f1] < dep[f2]) swap(f1, f2), swap(u, v);
func(dfn[f1], dfn[u], val...);
u = fa[f1]; f1 = top[u];
}
if (dep[u] < dep[v]) swap(u, v);
func(dfn[v], dfn[u], val...); // change here if you want the info on edges.
} /// end-hash
template<class T> /// start-hash
T chainAsk(int u, int v, const function<T(int, int)> &func) {
int f1 = top[u], f2 = top[v];
T ans{};
while (f1 != f2) {
if (dep[f1] < dep[f2]) swap(f1, f2), swap(u, v);
ans = ans + func(dfn[f1], dfn[u]);
u = fa[f1]; f1 = top[u];
}
if (dep[u] < dep[v]) swap(u, v);
ans = ans + func(dfn[v], dfn[u]); // change here if you want the info on edges.
return ans;
} /// end-hash
};
/**
* Author: Yuhao Yao
* Date: 22-09-27
* Description: Fenwick Tree.
*/
template<class T> struct BIT {
int n;
vector<T> a;
BIT(int n): n(n), a(n + 1, 0) {}
void Add(int i, T x) {
for (++i; i <= n; i += i & -i) a[i] += x;
}
T Ask(int i) {
T ans{};
for (++i; i; i -= i & -i) ans += a[i];
return ans;
}
T rangeAsk(int l, int r) { return Ask(r) - Ask(l - 1); }
// assuming prefix sums are non-decreasing, finds the first pos such that ask(pos) >= x.
int lower_bound(T x) {
assert(n > 0);
int pos = 0;
for (int h = 1 << __lg(n); h; h >>= 1) {
if ((pos | h) <= n && a[pos | h] < x) {
pos |= h;
x -= a[pos];
}
}
return pos;
}
};
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int n; cin >> n;
vvi g(n);
rep(i, 1, n - 1) {
int x, y; cin >> x >> y;
x--; y--;
g[x].push_back(y);
g[y].push_back(x);
}
HLD hld(g);
auto fa = hld.fa;
auto tin = hld.dfn;
vi tout(n);
auto getdfn = [&](auto &dfs, int now, int fa) -> void {
tout[now] = tin[now];
for (auto v: g[now]) if (v != fa) {
dfs(dfs, v, now);
chmax(tout[now], tout[v]);
}
};
getdfn(getdfn, 0, -1);
vector<pii> pairs;
rep(x, 1, n) rep(y, x, n) {
if (1ll * x * y > n) break;
pairs.emplace_back(x, y);
}
sort(all(pairs), [](pii a, pii b) { return 1ll * a.first * a.second < 1ll * b.first * b.second; });
BIT<ll> bit(n), bit2(n);
auto ptr = pairs.begin();
vector<ll> tag(n), tag1(n), tag2(n);
rep(z, 1, n) {
int now = z - 1;
while (ptr != pairs.end() && 1ll * ptr->first * ptr->second < z) {
auto [x, y] = *ptr;
ptr++;
int u = x - 1;
int v = y - 1;
int lca = hld.lca(u, v);
if (lca > 1ll * x * y && fa[lca] != -1) {
tag2[fa[lca]]++;
}
bit.Add(tin[u], 1);
bit.Add(tin[v], 1);
bit.Add(tin[lca], -1);
if (fa[lca] != -1) bit.Add(fa[lca], -1);
bit2.Add(tin[u], 1);
bit2.Add(tin[v], 1);
bit2.Add(tin[lca], -2);
}
tag[now] = bit.rangeAsk(tin[now], tout[now]);
for (auto v: g[now]) if (v != fa[now]) {
tag1[v] += tag[now] - bit2.rangeAsk(tin[v], tout[v]);
}
}
ll tot = accumulate(all(tag2), 0ll);
auto dfs = [&](auto &dfs, int now, int fa) -> void {
tag[now] += tot;
for (auto v: g[now]) if (v != fa) {
tag1[v] += tag1[now];
dfs(dfs, v, now);
tag[now] -= tag2[v];
tag2[now] += tag2[v];
}
};
dfs(dfs, 0, -1);
rep(now, 0, n - 1) {
ll ans = 1ll * n * (n + 1) / 2 - (tag[now] + tag1[now]);
printf("%lld\n", ans);
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 2ms
memory: 3532kb
input:
5 1 2 4 2 2 5 3 5
output:
15 15 15 15 14
result:
ok 5 number(s): "15 15 15 15 14"
Test #2:
score: -100
Wrong Answer
time: 1134ms
memory: 56760kb
input:
300000 40632 143306 32259 40632 225153 143306 269774 225153 289668 40632 191636 269774 85717 191636 58564 191636 156509 143306 289939 40632 247103 269774 40257 40632 98149 289668 142277 143306 291616 40257 46813 225153 56324 143306 277154 142277 53903 289668 114266 32259 152231 58564 241151 152231 4...
output:
45000149793 44999832537 44999853607 44999852570 44998954539 44999864802 44999256389 44999005619 44998983214 44998979007 44999840973 44998986182 44999136430 44999365672 45003278514 44999488335 44998971810 44999174184 44999185111 44998976124 44999781959 44999233996 44999500826 44999002892 44999371972 ...
result:
wrong answer 1st numbers differ - expected: '44999437117', found: '45000149793'