求助图上 insert
  • 板块灌水区
  • 楼主_Fatalis_
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/7/16 17:05
  • 上次更新2023/10/27 20:01:06
查看原帖
求助图上 insert
414231
_Fatalis_楼主2022/7/16 17:05

今天打树剖,然后程序在读入之前就 TLE 了

现在猜测是 Insert 常数过大

还有什么原因???

#include <cstdio>
#include <cstring>
#include <vector>
// #pragma GCC optimize(fast)

#define int long long
#define maxn 100004

#define max(a, b) ((a) > (b) ? (a) : (b))
template <typename T> struct segmt {
    struct tree {
        int l, r, lc, rc;
        T ans, lazy2;
        T ansMax;
    } tr[4 * maxn];
    T a[maxn];
    int tot, n;
    inline void init(int nn) {
        tot = 0;
        n = nn;
        memset(a, 0, sizeof(int) * (n + 10));
    }
    inline int bt(int l, int r) {
        int pos = ++tot;
        tr[pos].l = l;
        tr[pos].r = r;
        tr[pos].lazy2 = 0;
        if (l == r) {
            tr[pos].lc = tr[pos].rc = -1;
            tr[pos].ans = a[l];
            tr[pos].ansMax = a[l];
        } else {
            tr[pos].lc = bt(l, l + r >> 1);
            tr[pos].rc = bt((l + r >> 1) + 1, r);
            tr[pos].ans = (tr[tr[pos].lc].ans + tr[tr[pos].rc].ans);
            tr[pos].ansMax = max(tr[tr[pos].lc].ansMax, tr[tr[pos].rc].ansMax);
        }
        return pos;
    }
    inline void update(int pos) {
        if (tr[pos].lazy2) {
            change(tr[pos].lc, tr[tr[pos].lc].l, tr[tr[pos].lc].r, tr[pos].lazy2);
            change(tr[pos].rc, tr[tr[pos].rc].l, tr[tr[pos].rc].r, tr[pos].lazy2);
            tr[pos].lazy2 = 0;
        }
        tr[pos].ans = (tr[tr[pos].lc].ans + tr[tr[pos].rc].ans);
        tr[pos].ansMax = max(tr[tr[pos].lc].ansMax, tr[tr[pos].rc].ansMax);
    }
    inline void change(int pos, int l, int r, T x) {
        if (tr[pos].l == l && tr[pos].r == r) {
            tr[pos].lazy2 = (tr[pos].lazy2 + x);
            tr[pos].ans = x * (r - l + 1);
            tr[pos].ansMax = x;
            return;
        }
        update(pos);
        if (r <= tr[tr[pos].lc].r)
            change(tr[pos].lc, l, r, x);
        else if (l >= tr[tr[pos].rc].l)
            change(tr[pos].rc, l, r, x);
        else {
            change(tr[pos].lc, l, tr[tr[pos].lc].r, x);
            change(tr[pos].rc, tr[tr[pos].rc].l, r, x);
        }
        tr[pos].ans = (tr[tr[pos].lc].ans + tr[tr[pos].rc].ans);
        tr[pos].ansMax = max(tr[tr[pos].lc].ansMax, tr[tr[pos].rc].ansMax);
    }
    inline int query1(int pos, int l, int r) {
        if (tr[pos].l == l && r == tr[pos].r)
            return tr[pos].ans;
        update(pos);
        if (r <= tr[tr[pos].lc].r)
            return query1(tr[pos].lc, l, r);
        else if (l >= tr[tr[pos].rc].l)
            return query1(tr[pos].rc, l, r);
        else
            return query1(tr[pos].lc, l, tr[tr[pos].lc].r) +
                            query1(tr[pos].rc, tr[tr[pos].rc].l, r);
    }
    inline int query2(int pos, int l, int r) {
        if (tr[pos].l == l && r == tr[pos].r)
            return tr[pos].ansMax;
        update(pos);
        if (r <= tr[tr[pos].lc].r)
            return query2(tr[pos].lc, l, r);
        else if (l >= tr[tr[pos].rc].l)
            return query2(tr[pos].rc, l, r);
        else
            return max(query2(tr[pos].lc, l, tr[tr[pos].lc].r), 
                            query2(tr[pos].rc, tr[tr[pos].rc].l, r));
    }
};
segmt<int> sg;

struct Edge {
    int from, to, nxt, w, id;
};
Edge e[4 * maxn];
int head[maxn];
int EdgeToPoint[maxn];
int cnt = 0;
int n;
int Fa[maxn], Dep[maxn], Siz[maxn], Son[maxn], Top[maxn], dnk[maxn], rnk[maxn];
void init(int n) {
    memset(head, -1, sizeof(int) * (n + 10));
    // memset(EdgeToPoint, 0, sizeof(int) * (n + 10));
    // memset(Fa, 0, sizeof(int) * (n + 10));
    // memset(Dep, 0, sizeof(int) * (n + 10));
    // memset(Siz, 0, sizeof(int) * (n + 10));
    // memset(Son, 0, sizeof(int) * (n + 10));
    // memset(Top, 0, sizeof(int) * (n + 10));
    // memset(dnk, 0, sizeof(int) * (n + 10));
    // memset(rnk, 0, sizeof(int) * (n + 10));
    cnt = 0;
}
void insert(int from, int to, int wei, int id) {
    // e[cnt].from = from;
    e[cnt].to = to;
    e[cnt].nxt = head[from];
    e[cnt].w = wei;
    e[cnt].id = id;
    head[from] = cnt++;
}
void dfs1(int cur, int fa) {
    Fa[cur] = fa;
    Siz[cur] = 1;
    Son[cur] = -1;
    if (fa == -1) Dep[cur] = 0;
    else Dep[cur] = Dep[fa] + 1;
    for (int p = head[cur]; p != -1; p = e[p].nxt) {
        if (e[p].to == Fa[cur]) continue;
        dfs1(e[p].to, cur);
        if (Son[cur] == -1 || Siz[Son[cur]] < Siz[e[p].to]) {
            Son[cur] = e[p].to;
        }
        Siz[cur] += Siz[e[p].to];
        // puts("fk1");
    }
}
int tot;
void dfs2(int cur, int nowTop) {
    Top[cur] = nowTop;
    tot++;
    dnk[cur] = tot; rnk[tot] = cur;
    if (Son[cur] == -1) return;
    dfs2(Son[cur], nowTop);
    for (int p = head[cur]; p != -1; p = e[p].nxt) {
        if (e[p].to == Son[cur]) {
            sg.a[dnk[e[p].to]] = e[p].w;
            EdgeToPoint[e[p].id] = e[p].to;
        }
        if (e[p].to == Fa[cur] || e[p].to == Son[cur]) continue;
        dfs2(e[p].to, e[p].to);
        sg.a[dnk[e[p].to]] = e[p].w;
        EdgeToPoint[e[p].id] = e[p].to;
    }
}

signed main() {
    // freopen("P4114_10.in", "r", stdin);
    // freopen("P4114_10.ans", "w", stdout);
    int T = 1;
    // scanf("%lld", &T);
    while (T--) {
        int n;
        scanf("%lld", &n);
        sg.init(n);
        init(n);
        for (int i = 1; i < n; i++) {
            int x, y, w;
            scanf("%lld%lld%lld", &x, &y, &w);
            insert(x, y, w, i);
            insert(y, x, w, i);
        }
        puts("fk");   // 在 WA 之前 TLE
        dfs1(1, -1);
        tot = 0; dfs2(1, 1);
        sg.bt(1, n);
        while (true) {
            static char ch[1145]; int u, v;
            scanf("%s", ch);
            if (ch[0] == 'D') {
                break;
            } else {
                scanf("%lld%lld", &u, &v);
            }
            if (ch[0] == 'C') {
                sg.change(1, dnk[EdgeToPoint[u]], dnk[EdgeToPoint[u]], v);
            } else {
                int l = u, r = v;
                int maxx = 0;
                while (Top[l] != Top[r]) {
                    if (Dep[Top[l]] > Dep[Top[r]]) std::swap(l, r);
                    maxx = max(maxx, sg.query2(1, dnk[Top[r]], dnk[r]));
                    r = Fa[Top[r]];     
                } if (dnk[l] > dnk[r]) std::swap(l, r);
                // printf("%lld %lld\n", l, r);
                if (l == r) {
                    printf("%lld\n", maxx);
                    continue;
                }
                l = Son[l];
                if (l != -1) maxx = max(maxx, sg.query2(1, dnk[l], dnk[r]));
                printf("%lld\n", maxx);
            }
        }
    }
    return 0;
}
2022/7/16 17:05
加载中...