社区讨论
求助点分治75pts
P4149[IOI 2011] Race参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lo161ur6
- 此快照首次捕获于
- 2023/10/22 15:47 2 年前
- 此快照最后确认于
- 2023/11/02 15:22 2 年前
CPP
#include <iostream>
#include <vector>
#define mn 200010
#define T tr[now]
#define inf 0x3f3f3f3f
using namespace std;
int n, K;
int ans = inf;
struct treap
{
int ls, rs;
int val;
int dep;
int siz;
int rnd;
} tr[mn];
int root, cnt;
int x, y, z, w;
inline void pushup(int now)
{
T.siz = tr[T.ls].siz + tr[T.rs].siz + 1;
}
inline void split(int now, int k, int dep, int &x, int &y)
{
if (!now)
{
x = y = 0;
return;
}
if (T.val < k)
{
x = now;
split(T.rs, k, dep, T.rs, y);
}
else if (T.val > k)
{
y = now;
split(T.ls, k, dep, x, T.ls);
}
else
{
if (T.dep <= dep)
{
x = now;
split(T.rs, k, dep, T.rs, y);
}
else
{
y = now;
split(T.ls, k, dep, x, T.ls);
}
}
pushup(now);
}
inline int merge(int A, int B)
{
if (!A || !B)
return A | B;
if (tr[A].rnd < tr[B].rnd)
{
tr[A].rs = merge(tr[A].rs, B);
pushup(A);
return A;
}
else
{
tr[B].ls = merge(A, tr[B].ls);
pushup(B);
return B;
}
}
inline int add(int k, int dep)
{
tr[++cnt].val = k;
tr[cnt].dep = dep;
tr[cnt].siz = 1;
tr[cnt].rnd = rand();
return cnt;
}
inline void ins(int k, int dep)
{
split(root, k, dep, x, y);
root = merge(merge(x, add(k, dep)), y);
}
inline int kth(int now, int k)
{
while (1)
{
if (k <= tr[T.ls].siz)
now = T.ls;
else if (k == tr[T.ls].siz + 1)
return T.dep;
else
{
k -= tr[T.ls].siz + 1;
now = T.rs;
}
}
}
inline int getrk(int k)
{
split(root, k - 1, inf, x, y);
split(y, k, inf, y, w);
split(y, k, -1, y, z);
if (!z)
return inf;
int res = kth(z, 1);
root = merge(merge(merge(x, y), z), w);
return res;
}
inline void clear()
{
for (int i = 1; i <= cnt; ++i)
tr[i].ls = tr[i].rs = 0;
}
struct node
{
int to;
int val;
};
vector<node>G[mn];
int siz[mn];
int vis[mn];
int rt, rt_siz;
int tr_siz;
inline void getsiz(int u, int fa)
{
siz[u] = 1;
for (node v : G[u])
{
if (v.to == fa || vis[v.to])
continue;
getsiz(v.to, u);
siz[u] += siz[v.to];
}
}
inline void getrt(int u, int fa)
{
int max_part = 0;
for (node v : G[u])
{
if (v.to == fa || vis[v.to])
continue;
getrt(v.to, u);
max_part = max(max_part, siz[v.to]);
}
max_part = max(max_part, tr_siz - siz[u]);
if (max_part < rt_siz)
{
rt_siz = max_part;
rt = u;
}
}
inline void count(int u, int fa, int k, int dep)
{
if (k > K)
return;
ans = min(ans, getrk(K - k) + dep);
for (node v : G[u])
{
if (v.to == fa || vis[v.to])
continue;
count(v.to, u, k + v.val, dep + 1);
}
}
inline void update(int u, int fa, int k, int dep)
{
ins(k, dep);
for (node v : G[u])
{
if (v.to == fa || vis[v.to])
continue;
update(v.to, u, k + v.val, dep + 1);
}
}
inline void solve(int u, int fa)
{
getsiz(u, fa);
tr_siz = siz[u];
rt = 0, rt_siz = inf;
getrt(u, fa);
u = rt;
vis[u] = 1;
ins(0, 0);
for (node v : G[u])
{
if (v.to == fa || vis[v.to])
continue;
count(v.to, u, v.val, 1);
update(v.to, u, v.val, 1);
}
clear();
root = cnt = 0;
for (node v : G[u])
{
if (v.to == fa || vis[v.to])
continue;
solve(v.to, u);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> K;
for (int i = 1, u, v, w; i <= n - 1; ++i)
{
cin >> u >> v >> w;
G[u].push_back({v, w});
G[v].push_back({u, w});
}
solve(0, -1);
if (ans > n)
cout << -1;
else
cout << ans;
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...