QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#65464#4839. Smaller LCAYaoBIGWA 1134ms56760kbC++176.6kb2022-12-01 09:33:292022-12-01 09:33:32

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-12-01 09:33:32]
  • 评测
  • 测评结果:WA
  • 用时:1134ms
  • 内存:56760kb
  • [2022-12-01 09:33:29]
  • 提交

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'