3log暴力 点分 + 线段树求帮忙看看
查看原帖
3log暴力 点分 + 线段树求帮忙看看
168223
ShuKuang楼主2022/6/5 08:25

这是代码

#include <bits/stdc++.h>
using namespace std;

namespace IO {
    template <typename T>
    inline void read(T &x) {
        x = 0; T r = 1;
        char ch = getchar();
        while (!isdigit(ch)) r = ch == '-' ? -1 : 1, ch = getchar();
        while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
        x *= r;
    }

    template <typename T, typename ...Args>
    void read(T &x, Args &...args) {
        read(x), read(args...);
    }

    template <typename T>
    inline void write(T x) {
        if (x < 0) putchar('-'), x = -x;
        if (x > 9) write(x / 10);
        putchar(x % 10 + '0');
    }
}

using namespace IO;

using db = double;
using pd = pair<int, db>;
using pii = pair<int, int>;

#define inf 0x3f3f3f3f
#define fi first
#define se second
#define pc putchar
#define eb emplace_back

const int N = 1e5 + 10;
namespace Seg {
    struct node {
        int l, r;
        db mx;
    } t[N << 2];

    #define ls (p << 1)
    #define rs (p << 1 | 1)
    #define mid ((l + r) >> 1)

    void build(int p, int l, int r) {
        t[p].l = l; t[p].r = r; t[p].mx = -inf;
        if (l == r) return;
        build(ls, l, mid); build(rs, mid + 1, r);
    }

    void modify(int p, int pos, db val) {
        if (t[p].l > pos || t[p].r < pos) return;
        if (t[p].l == t[p].r) return t[p].mx = max(t[p].mx, val), void();
        modify(ls, pos, val); modify(rs, pos, val);
        t[p].mx = max(t[ls].mx, t[rs].mx);
    }

    db query(int p, int L, int R) {
        if (t[p].l > R || t[p].r < L) return -inf;
        if (t[p].l >= L && t[p].r <= R) return t[p].mx;
        return max(query(ls, L, R), query(rs, L, R));
    }

    #undef ls
    #undef rs
    #undef mid
}

int n, L, R, len;

struct Edge {
    int nxt, to;
    db val;
}e[N << 1];

int head[N], cnte;

void link(int x, int y, db z) {
    e[++ cnte] = {head[x], y, z};
    head[x] = cnte;
}

int siz[N], ms[N], rt;
bool vis[N];

db res;
void get_rt(int u, int fath, int all) {
    siz[u] = 1; ms[u] = 0;
    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        if (v == fath || vis[v]) continue;
        get_rt(v, u, all);
        siz[u] += siz[v];
        ms[u] = max(ms[u], siz[v]);
    }
    ms[u] = max(ms[u], all - siz[u]);
    if (!rt || ms[u] < ms[rt]) rt = u;
}

vector<pd> g;

void dfs(int u, int fath, int dis, db val, db x) {
    g.eb(pd(dis, val));
    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        db w = e[i].val - x;
        if (v == fath || vis[v]) continue;
        if (dis + 1 > R) continue;
        dfs(v, u, dis + 1, val + w, x);
    }
}

void solve(int u, db x) {
    vis[u] = 1;
    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        db w = e[i].val - x;
        if (vis[v]) continue;
        dfs(v, u, 1, w, x);
        for (auto now : g) {
            if (now.fi < L) res = max(res, now.se + Seg :: query(1, L - now.fi, R - now.se));
            else if (now.fi >= L && now.fi <= R) res = max(res, now.se + Seg :: query(1, 1, R - now.se));
            else continue;
        }
        for (auto now : g) Seg :: modify(1, now.fi, now.se);
        g.clear();
    }
    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        if (vis[v]) continue;
        rt = 0; get_rt(v, 0, siz[v]); solve(rt, x);
    }
}

void Clear() {
    Seg :: build(1, 1, R);
    res = -inf;
    memset(vis, 0, sizeof vis);
    rt = 0;
}

bool chk(db x) {
    Clear();
    get_rt(1, 0, n); solve(rt, x);
    return res >= 0;
}

signed main() {
    #ifndef ONLINE_JUDGE 
        freopen("test.in", "r", stdin);
    #endif  
    read(n, L, R);
    for (int i = 1; i < n; ++ i) {
        int u, v, w;
        read(u, v, w);
        link(u, v, (db)w);
        link(v, u, (db)w);
    }
    db l = 0, r = 1e6;
	while (r - l > 1e-4) {
		db mid = (l + r) / 2.0;
		if (chk(mid)) l = mid;
		else r = mid;
	}
    printf("%.3lf\n", l);
    return 0;
}
2022/6/5 08:25
加载中...