QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#65465 | #4839. Smaller LCA | YaoBIG | WA | 1365ms | 55904kb | C++17 | 6.5kb | 2022-12-01 09:36:58 | 2022-12-01 09:37:01 |
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) {
tag2[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 {
for (auto v: g[now]) if (v != fa) {
tag1[v] += tag1[now];
tag2[v] += tag2[now];
dfs(dfs, v, now);
}
};
dfs(dfs, 0, -1);
rep(now, 0, n - 1) {
ll ans = 1ll * n * (n + 1) / 2 - (tag[now] + tag1[now] + tot - tag2[now]);
printf("%lld\n", ans);
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 3644kb
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: 1365ms
memory: 55904kb
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:
44999437122 45000307327 45000331956 45000330917 44999549686 45000347973 44999874406 44999614807 44999580523 44999620598 45000317668 44999627843 44999760068 44999428458 45003764956 44999937807 44999612042 44999794085 44999804851 44999616318 45000255366 44999854067 44999950325 44999611886 44999414107 ...
result:
wrong answer 1st numbers differ - expected: '44999437117', found: '44999437122'