莫名 RE 球调,玄关
查看原帖
莫名 RE 球调,玄关
300098
cmaths楼主2023/12/27 10:45
#include <bits/stdc++.h>
#define lx (x * 2)
#define rx (x * 2 + 1)
#define mid ((l + r) >> 1)
#define ll long long

using namespace std;

int read()
{
    int x = 0, f = 1;
    char ch = 0;
    while(!isdigit(ch))
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(isdigit(ch))
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

const int N = 100000, LG = 20;
ll INF = (ll)0x3f3f3f3f3f3f3f3f;
int n, q;

struct Edge
{
    int v;
    ll w;
    int nxt;
}edge[N * 2 + 5];
int head[N + 5], cnte;
void adde(int u, int v, ll w)
{
    edge[++cnte] = {v, w, head[u]};
    head[u] = cnte;
}

ll dep[N + 5];
int dep1[N + 5];
int fa[N + 5], siz[N + 5], hson[N + 5];
struct St
{
    int id, dep;
    bool operator < (const St &t) const
    {
        return dep < t.dep;
    }
}st[N * 2 + 5][LG + 5];
int cnts;
int sta[N + 5], ed[N + 5];
void dfs1(int u, int fath)
{
    dep1[u] = dep1[fath] + 1;
    st[++cnts][0] = {u, dep1[u]};
    sta[u] = cnts;
    fa[u] = fath;
    siz[u] = 1;
    for(int i = head[u]; i; i = edge[i].nxt)
    {
        int v = edge[i].v;
        if(v == fath)
        {
            continue;
        }
        dep[v] = dep[u] + edge[i].w;
        dfs1(v, u);
        st[++cnts][0] = {u, dep1[u]};
        siz[u] += siz[v];
        if(siz[v] > siz[hson[u]])
        {
            hson[u] = v;
        }
    }
    ed[u] = cnts;
}
int dfn[N + 5], rk[N + 5], cntn;
int tp[N + 5];
void dfs2(int u, int topp)
{
    dfn[u] = ++cntn;
    rk[cntn] = u;
    tp[u] = topp;
    if(hson[u])
    {
        dfs2(hson[u], topp);
    }
    for(int i = head[u]; i; i = edge[i].nxt)
    {
        int v = edge[i].v;
        if(v == fa[u] || v == hson[u])
        {
            continue;
        }
        dfs2(v, v);
    }
}
int l2[N * 2 + 5];
void STP()
{
    l2[1] = 0;
    for(int i = 2; i <= cnts; i++)
    {
        l2[i] = l2[i / 2] + 1;
    }
    for(int i = cnts; i >= 1; i--)
    {
        for(int j = 1; j <= LG; j++)
        {
            if(i + (1 << j) - 1 > cnts)
            {
                break;
            }
            st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int LCA(int x, int y)
{
    if(ed[x] > sta[y])
    {
        swap(x, y);
    }
    int s = ed[x], t = sta[y];
    int tmp = l2[t - s + 1];
    return min(st[s][tmp], st[t - (1 << tmp) + 1][tmp]).id;
}
int dis(int x, int y)
{
    return dep[x] + dep[y] - 2 * dep[LCA(x, y)];
}

struct Seg
{
    ll k, b;
    Seg()
    {
        k = INF, b = INF;
    }
    Seg(ll kk, ll bb)
    {
        k = kk, b = bb;
    }
    ll calc(ll x)
    {
        if(k == INF)
        {
            return INF;
        }
        return k * x + b;
    }
};
struct Tr
{
    Seg x;
}lc[N * 4 + 5];
void add(int x, int l, int r, int s, int t, Seg k)
{
    if(l >= s && r <= t)
    {
        int z1 = dep[rk[l]], z2 = dep[rk[mid]], z3 = dep[rk[r]];
        // if(lc[x].x.k == INF)
        // {
        //     lc[x].x = k;
        //     // printf("%d %d %lld %lld 111\n", l, r, k.k, k.b);
        //     return;
        // }
        if(k.calc(z2) <= lc[x].x.calc(z2))
        {
            swap(k, lc[x].x);
        }
        if(k.calc(z1) >= lc[x].x.calc(z1) && k.calc(z3) >= lc[x].x.calc(z3))
        {
            return;
        }
        if(l == r)
        {
            return;
        }
        if(k.calc(z1) <= lc[x].x.calc(z1))
        {
            add(lx, l, mid, s, t, k);
        }
        else
        {
            add(rx, mid + 1, r, s, t, k);
        }
        return;
    }
    if(s <= mid)
    {
        add(lx, l, mid, s, t, k);
    }
    if(t > mid)
    {
        add(rx, mid + 1, r, s, t, k);
    }
}
ll ask(int x, int l, int r, int s)
{
    if(l == r)
    {
        return lc[x].x.calc(dep[rk[s]]);
    }
    ll ret = lc[x].x.calc(dep[rk[s]]);
    if(s <= mid)
    {
        ret = min(ret, ask(lx, l, mid, s));
    }
    else
    {
        ret = min(ret, ask(rx, mid + 1, r, s));
    }
    return ret;
}
struct TT
{
    ll mx;
}tr[N * 4 + 5];
void pushup(int x)
{
    tr[x].mx = min(tr[lx].mx, tr[rx].mx);
}
void build(int x, int l, int r)
{
    if(l == r)
    {
        tr[x].mx = (ll)123456789123456789;
        return;
    }
    build(lx, l, mid);
    build(rx, mid + 1, r);
    pushup(x);
}
void mdf(int x, int l, int r, int s, ll k)
{
    if(l == r)
    {
        tr[x].mx = min(tr[x].mx, k);
        return;
    }
    if(s <= mid)
    {
        mdf(lx, l, mid, s, k);
    }
    else
    {
        mdf(rx, mid + 1, r, s, k);
    }
    pushup(x);
    return;
}
ll ask1(int x, int l, int r, int s, int t)
{
    if(l >= s && r <= t)
    {
        return tr[x].mx;
    }
    ll ret = INF;
    if(s <= mid)
    {
        ret = min(ret, ask1(lx, l, mid, s, t));
    }
    if(t > mid)
    {
        ret = min(ret, ask1(rx, mid + 1, r, s, t));
    }
    return ret;
}

void addchn(int x, int y, Seg k)
{
    while(1)
    {
        // printf("%d\n", x);
        if(dep1[tp[x]] > dep1[y])
        {
            add(1, 1, n, dfn[tp[x]], dfn[x], k);
            // printf("%d %d 333\n", dfn[tp[x]], dfn[x]);
            mdf(1, 1, n, dfn[x], k.calc(dep[x]));
            mdf(1, 1, n, dfn[tp[x]], k.calc(dep[tp[x]]));
            x = fa[tp[x]];
        }
        else
        {
            add(1, 1, n, dfn[y], dfn[x], k);
            mdf(1, 1, n, dfn[x], k.calc(dep[x]));
            mdf(1, 1, n, dfn[y], k.calc(dep[y]));
            break;
        }
    }
}
ll askchn(int x, int y)
{
    ll ret = INF;
    while(1)
    {
        if(dep1[tp[x]] > dep1[y])
        {
            ret = min(ret, ask(1, 1, n, dfn[x]));
            ret = min(ret, ask(1, 1, n, dfn[tp[x]]));
            ret = min(ret, ask1(1, 1, n, dfn[tp[x]], dfn[x]));
            x = fa[tp[x]];
        }
        else
        {
            ret = min(ret, ask(1, 1, n, dfn[x]));
            ret = min(ret, ask(1, 1, n, dfn[y]));
            ret = min(ret, ask1(1, 1, n, dfn[y], dfn[x]));
            // printf("%d %d 222\n", dfn[y], dfn[x]);s
            break;
        }
    }
    return ret;
}

void init()
{
    n = read(), q = read();
    for(int i = 1; i < n; i++)
    {
        int u = read(), v = read();
        ll w = (ll)read();
        adde(u, v, w);
        adde(v, u, w);
    }
    dfs1(1, 0);
    STP();
    dfs2(1, 1);
}

void solve()
{
    // for(int i = 1; i <= n; i++)
    // {
    //     printf("%d ", tp[i]);
    // }
    // printf("\n");
    build(1, 1, n);
    while(q--)
    {
        int op = read();
        if(op == 1)
        {
            int x = read(), y = read(), k = read(), b = read();
            int lca = LCA(x, y);
            addchn(x, lca, Seg(-k, (ll)k * dep[x] + b));
            addchn(y, lca, Seg(k, (ll)k * (dep[x] - dep[lca] - dep[lca]) + b));
            // printf("%d %d %lld %lld\n", x, lca, -(ll)k, (ll)k * dep[x] + b);
            // printf("%d %d %lld %lld\n", y, lca, (ll)k, (ll)k * (dep[x] - dep[lca] - dep[lca]) + b);
        }
        else
        {
            int x = read(), y = read();
            int lca = LCA(x, y);
            printf("%lld\n", min(askchn(x, lca), askchn(y, lca)));
        }
        // printf("suc %d\n", q);
    }
}

int main()
{
    // freopen("in.in", "r", stdin);
    // freopen("my.out", "w", stdout);
    init();
    solve();
    return 0;
}

vs 提示段错误

2023/12/27 10:45
加载中...