什么?点分治!
查看原帖
什么?点分治!
217289
bryce楼主2024/8/16 10:17

代码求调:第2,10个点TLE

#include<iostream>
#include<climits>
#include<algorithm>
#define int long long

using namespace std;

inline int read(){register int x = 0, f = 1;register char c = getchar();while (c < '0' || c > '9'){if (c == '-') f = -1;c = getchar();}while (c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return x * f;}
inline void write(int x){if (x < 0) putchar('-'), x = -x;if (x > 9) write(x / 10);putchar(x % 10 + '0');}

const int N = 2e5 + 10;
int n, m, L, R, rt, ans = INT_MIN;
int c[N];
int t1[N << 2], t2[N << 2];
void pushup(int now, int t[]){
    t[now] = max(t[now << 1], t[now << 1 | 1]);
}
void build(int now, int l, int r, int t[]){
    if (l == r){
        t[now] = LLONG_MIN;
        return;
    }
    int mid = (l + r) >> 1;
    build(now << 1, l, mid, t);
    build(now << 1 | 1, mid + 1, r, t);
    pushup(now, t);
}
void modify(int now, int l, int r, int x, int k, int t[]){
    if (l == r){
        if (k == LLONG_MIN) t[now] = k;
        else t[now] = max(t[now], k);
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) modify(now << 1, l, mid, x, k, t);
    else modify(now << 1 | 1, mid + 1, r, x, k, t);
    pushup(now, t);
}
int query(int now, int l, int r, int x, int y, int t[]){
    if (x <= l && r <= y) return t[now];
    int mid = (l + r) >> 1, res = LLONG_MIN;
    if (x <= mid) res = max(res, query(now << 1, l, mid, x, y, t));
    if (mid + 1 <= y) res = max(res, query(now << 1 | 1, mid + 1, r, x, y, t));
    return res;
}
struct edge{
    int v, w, col, nxt;
}e[N << 1];
int head[N], cnt;
void add(int u, int v, int w, int col){
    e[++cnt] = (edge){v, w, col, head[u]};
    head[u] = cnt;
}
struct node{
    int dis, l, c, id;
    bool operator < (const node &b) const{
        if (c != b.c) return c < b.c;
        return id < b.id;
    }
}stk[N];
int sz[N], mx[N], maxn, top, dis[N], l[N];
bool vis[N];
void find(int u, int fa){
    sz[u] = 1, mx[u] = 0;
    for (int i = head[u]; i; i = e[i].nxt){
        int v = e[i].v;
        if (v == fa || vis[v]) continue;
        find(v, u);
        sz[u] += sz[v];
        mx[u] = max(mx[u], sz[v]);
    }
    mx[u] = max(mx[u], maxn - sz[u]);
    if (mx[u] < mx[rt]) rt = u;
}
void dfs(int u, int fa, int col, int last, int id){
    stk[++top] = (node){dis[u], l[u], col, id};
    for (int i = head[u]; i; i = e[i].nxt){
        int v = e[i].v;
        if (v == fa || vis[v]) continue;
        if (e[i].col != last) dis[v] = dis[u] + e[i].w;
        else dis[v] = dis[u];
        l[v] = l[u] + 1;
        dfs(v, u, col, e[i].col, id);
    }
}
void calc(int u){
    top = 0;
    int id = 0;
    for (int i = head[u]; i; i = e[i].nxt){
        int v = e[i].v;
        if (vis[v]) continue;
        dis[v] = e[i].w, l[v] = 1;
        dfs(v, u, e[i].col, e[i].col, ++id);
    }
    sort(stk + 1, stk + top + 1);
    build(1, 1, top + 1, t1);
    build(1, 1, top + 1, t2);
    modify(1, 1, top + 1, 1, 0, t2);
    int l = 1, r = 1;
    for (int i = 1; i <= top; i++){
        if (stk[i].id != stk[i - 1].id && i != 1){
            if (stk[i].c == stk[i - 1].c){
                for (int j = l; j <= r; j++) modify(1, 1, top + 1, stk[j].l + 1, stk[j].dis, t1);
            }else{
                for (int j = l; j <= r; j++) modify(1, 1, top + 1, stk[j].l + 1, LLONG_MIN, t1), modify(1, 1, top + 1, stk[j].l + 1, stk[j].dis, t2);
                l = r = i;
            }
        }else r = i;
        int x = query(1, 1, top + 1, max(min(L - stk[i].l, top) + 1, 1ll), max(min(R - stk[i].l, top) + 1, 1ll) + 1, t1);
        int y = query(1, 1, top + 1, max(min(L - stk[i].l, top) + 1, 1ll), max(min(R - stk[i].l, top) + 1, 1ll), t2);
        if (x != LLONG_MIN) ans = max(ans, x - c[stk[i].c] + stk[i].dis);
        if (y != LLONG_MIN) ans = max(ans, y + stk[i].dis);
    }
}
void solve(int u){
    vis[u] = 1;
    calc(u);
    for (int i = head[u]; i; i = e[i].nxt){
        int v = e[i].v;
        if (vis[v]) continue;
        rt = 0;
        maxn = sz[v];
        find(v, 0);
        solve(rt);
    }
}

signed main(){
    n = read(), m = read(), L = read(), R = read();
    for (int i = 1; i <= m; i++) c[i] = read();
    for (int i = 1; i < n; i++){
        int u = read(), v = read(), col = read(), w = c[col];
        add(u, v, w, col), add(v, u, w, col);
    }
    maxn = mx[rt] = n;
    find(1, 0);
    solve(rt);
    cout << ans;
    return 0;
}
2024/8/16 10:17
加载中...