QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#57991 | #4839. Smaller LCA | MIT01# | TL | 0ms | 21180kb | C++17 | 2.9kb | 2022-10-24 07:52:16 | 2022-10-24 07:52:17 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb emplace_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()
template<typename T> inline bool chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
typedef long long LL;
const int oo = 0x3f3f3f3f;
const int max0 = 19;
const int maxn = 300100;
int n;
vector<int> adj[maxn + 5];
int fa[max0][maxn + 5];
int dep[maxn + 5];
int dfs_tot = 0;
int dfn[maxn + 5];
int End[maxn + 5];
LL sum[maxn + 5];
int seq[maxn + 5];
void dfs(int x, int f = -1)
{
seq[dfs_tot] = x;
dfn[x] = dfs_tot++;
if (~f) dep[x] = dep[f] + 1;
else dep[x] = 0;
fa[0][x] = f;
for (auto y : adj[x])
if (y != f) dfs(y, x);
End[x] = dfs_tot;
}
int lca(int x, int y)
{
if (dep[x] > dep[y]) swap(x, y);
for (int i = 0; dep[x] != dep[y]; ++i)
if ((dep[y] ^ dep[x]) >> i & 1) y = fa[i][y];
int s = max0 - 1;
while (x != y)
{
for ( ; s && fa[s][x] == fa[s][y]; --s);
x = fa[s][x];
y = fa[s][y];
}
return x;
}
int cnt[maxn + 5];
int ans[maxn + 5];
vector< pair<int, int> > pairs;
int fen[maxn + 5];
inline void add(int x, int y)
{
for (int i = x + 1; i <= n; i += i & -i)
fen[i] += y;
}
inline int query(int x)
{
int ret = 0;
for (int i = x; i > 0; i -= i & -i)
ret += fen[i];
return ret;
}
int main()
{
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
scanf("%d", &n);
REP(i, 0, n - 1)
{
int u, v;
scanf("%d%d", &u, &v), --u, --v;
adj[u].pb(v);
adj[v].pb(u);
}
dfs_tot = 0;
dfs(0);
REP(i, 1, max0) REP(j, 0, n)
if (~fa[i - 1][j]) fa[i][j] = fa[i - 1][fa[i - 1][j]];
else fa[i][j] = fa[i - 1][j];
for (int i = 1; i <= n; ++i)
for (int j = i; i * j <= n; ++j)
{
pairs.pb(mp(i - 1, j - 1));
int tmp = lca(i - 1, j - 1);
if ((tmp + 1) > (i + 1) * (j + 1)) ++cnt[tmp];
}
sort(ALL(pairs), [&](const pair<int, int> &x, const pair<int, int> &y) { return x.x * x.y < y.x * y.y; } );
memset(fen, 0, sizeof fen);
REP(i, 0, n)
{
int x = seq[i];
sum[x] = cnt[x];
if (~fa[0][x]) sum[x] += sum[fa[0][x]];
}
int tot = 0;
REP(i, 0, n) tot += cnt[i];
REP(i, 0, n) ans[i] = tot - sum[i];
int cur = 1;
for (auto u : pairs)
{
int x = u.x, y = u.y;
while (cur <= (x + 1) * (y + 1))
{
ans[cur - 1] += query(End[cur - 1]) - query(dfn[cur - 1]);
++cur;
}
add(dfn[x], 1);
add(dfn[y], 1);
int tmp = lca(x, y);
add(dfn[tmp], -1);
if (~fa[0][tmp])
add(dfn[fa[0][tmp]], -1);
}
REP(i, 0, n)
printf("%lld\n", ((LL)n * (n + 1) >> 1) - ans[i]);
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 21180kb
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
Time Limit Exceeded
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...