求助树剖
查看原帖
求助树剖
205435
Axxx楼主2020/5/19 21:21

RT,6 分树剖,调了很久了。。

#include <bits/stdc++.h>

using namespace std;

inline int gi()
{
	int f = 1, x = 0; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return f * x;
}

const int INF = 0x3f3f3f3f, N = 100003, M = N << 1;

int n, m;
struct Node
{
    int u, v;
} a[N];
int tot, head[N], ver[M], nxt[M];
int dep[N], fa[N], son[N], sz[N], topp[N], dfn[N], tim;
int tr[N << 4];

inline void add(int u, int v)
{
    ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}

void dfs1(int u, int f)
{
    fa[u] = f, sz[u] = 1, dep[u] = dep[f] + 1;
    for (int i = head[u]; i; i = nxt[i])
    {
        int v = ver[i];
        if (v == f) continue;
        dfs1(v, u);
        sz[u] += sz[v];
        if (sz[v] > sz[son[u]]) son[u] = v;
    }
}

void dfs2(int u, int f)
{
    topp[u] = f, dfn[u] = ++tim;
    if (!son[u]) return;
    dfs2(son[u], f);
    for (int i = head[u]; i; i = nxt[i])
    {
        int v = ver[i];
        if (v == fa[u] || v == son[u]) continue;
        dfs2(v, v);
    }
}

inline int ls(int p) {return p << 1;}
inline int rs(int p) {return p << 1 | 1;}

inline void pushup(int p)
{
    tr[p] = min(tr[ls(p)], tr[rs(p)]);
}

void build(int l, int r, int p)
{
    tr[p] = INF;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(l, mid, ls(p));
    build(mid + 1, r, rs(p));
}

void modify(int ql, int qr, int x, int l, int r, int p)
{
    if (ql <= l && r <= qr)
    {
        tr[p] = min(tr[p], x);
        return;
    }
    int mid = (l + r) >> 1;
    if (ql <= mid) modify(ql, qr, x, l, mid, ls(p));
    if (qr > mid) modify(ql, qr, x, mid + 1, r, rs(p));
    pushup(p);
}

int getans(int ql, int qr, int l, int r, int p)
{
    if (ql <= l && r <= qr) return tr[p];
    int mid = (l + r) >> 1, ans = INF;
    if (ql <= mid) ans = getans(ql, qr, l, mid, ls(p));
    if (qr > mid) ans = min(ans, getans(ql, qr, mid + 1, r, rs(p)));
    return ans;
}

inline void mchain(int u, int v, int x)
{
    while (topp[u] != topp[v]) 
    {
        if (dep[topp[u]] < dep[topp[v]]) swap(u, v);
        modify(dfn[topp[u]], dfn[u], x, 1, n, 1);
        u = fa[topp[u]];
    }
    if (dfn[u] > dfn[v]) swap(u, v);
    modify(dfn[u] + 1, dfn[v], x, 1, n, 1);
}

inline int qchain(int u, int v)
{
    int ans = INF;
    while (topp[u] != topp[v]) 
    {
        if (dep[topp[u]] < dep[topp[v]]) swap(u, v);
        ans = min(ans, getans(dfn[topp[u]], dfn[u], 1, n, 1));
        u = fa[topp[u]];
    }
    if (dfn[u] > dfn[v]) swap(u, v);
    ans = min(ans, getans(dfn[u] + 1, dfn[v], 1, n, 1));
    return ans;
}

int main()
{
	n = gi(), m = gi();
	for (int i = 1; i < n; i+=1)
	{
	    int u = gi(), v = gi();
	    add(u, v), add(v, u);
	    a[i] = (Node){u, v};
	}
	dfs1(1, 0);
	dfs2(1, 1);
	build(1, n, 1);
	for (int i = 1; i <= m; i+=1)
	{
	    int u = gi(), v = gi(), w = gi();
	    mchain(u, v, w);
	}
	for (int i = 1; i < n; i+=1)
	{
	    int ans = qchain(a[i].u, a[i].v);
	    if (ans == INF) puts("-1");
	    else printf("%d\n", ans);
	}
	return 0;
}
2020/5/19 21:21
加载中...