求优化常数
查看原帖
求优化常数
483928
Z1qqurat楼主2023/9/2 14:05

线段树分治+LCT,同样做法的老哥跑过了我愣是TLE了,求dalao教教我/kk

https://www.luogu.com.cn/record/123548961

#include <bits/stdc++.h>
#define ll long long
#define pii pair<int, int>
#define mr make_pair
#define fi first
#define se second
using namespace std;
const int N = 3e5 + 5;
int n, m, q;
bool qr[N];
ll sum;
struct Ed{
    int u, v, w, id;
}e1[N], e2[N];

namespace LCT{
    int fa[N], ch[N][2], ma[N], val[N], tag[N], stk[N];
    void pushup(int p) {
        ma[p] = val[p];
        int ls = ma[ch[p][0]], rs = ma[ch[p][1]];
        if(e2[ma[p]].w < e2[ls].w) ma[p] = ls; 
        if(e2[ma[p]].w < e2[rs].w) ma[p] = rs;
        return ; 
    }
    int child(int x) {
        return (ch[fa[x]][1] == x);
    }
    bool notroot(int x) {
        return (ch[fa[x]][0] == x || ch[fa[x]][1] == x);
    }
    void reverse(int x) {
        swap(ch[x][0], ch[x][1]), tag[x] ^= 1;
        return ;
    }
    void pushdown(int x) {
        if(tag[x]) {
            if(ch[x][0]) reverse(ch[x][0]);
            if(ch[x][1]) reverse(ch[x][1]);
            tag[x] = 0;
        }
        return ;
    }
    void rotate(int x) {
        int y = fa[x], z = fa[y], k = child(x), w = ch[x][k ^ 1];
        if(notroot(y)) ch[z][child(y)] = x;
        ch[x][k ^ 1] = y, ch[y][k] = w;
        if(w) fa[w] = y;
        fa[y] = x, fa[x] = z;
        pushup(y); return ;
    }
    void splay(int x) {
        int top = 0, y = x, z;
        stk[++top] = y;
        while(notroot(y)) stk[++top] = (y = fa[y]);
        while(top) pushdown(stk[top--]);
        while(notroot(x)) {
            y = fa[x], z = fa[y];
            if(notroot(y)) {
                if(child(x) == child(y)) rotate(y);
                else rotate(x);
            }
            rotate(x);
        }
        pushup(x); return ;
    }
    void access(int x) {
        for (int y = 0; x; y = x, x = fa[y]) {
            splay(x), ch[x][1] = y, pushup(x);
        }
        return ;
    }
    void makeroot(int x) {
        access(x), splay(x);
        reverse(x); return ;
    }
    int findroot(int x) {
        access(x), splay(x);
        while(ch[x][0]) pushdown(x), x = ch[x][0];
        splay(x); return x;
    }
    void makepath(int x, int y) {
        makeroot(x), access(y), splay(y);
        return ;
    }
    void link(int x, int y) {
        makeroot(x);
        if(findroot(y) != x) fa[x] = y;
    }
    void cut(int x, int y) {
        makeroot(x);
        if(findroot(y) == x && fa[y] == x && (!ch[y][0])) {
            fa[y] = ch[x][1] = 0, pushup(x);
        }
    }
} using namespace LCT;

vector <int> tr[N << 2];
vector <pii> del;

void modify(int p, int l, int r, int x, int y, int v) {
    if(x <= l && r <= y) {
        tr[p].emplace_back(v); return ;
    }
    int mid = (l + r) >> 1;
    if(x <= mid) modify(p << 1, l, mid, x, y, v);
    if(y > mid) modify(p << 1 | 1, mid + 1, r, x, y, v);
    return ;
}

void insert(int d) {
    int u = e2[d].u, v = e2[d].v, w = e2[d].w, id = e2[d].id;
    makeroot(u);
    if(findroot(v) != u) {
        sum += w;
        link(u, id + n), link(v, id + n);
        del.emplace_back(mr(id, -1));
        return ;
    }
    makepath(u, v);
    int mx = ma[v];
    if(w < e2[mx].w) {
        sum -= e2[mx].w, sum += w;
        cut(e2[mx].u, e2[mx].id + n), cut(e2[mx].v, e2[mx].id + n);
        del.emplace_back(mr(mx, 1));
        link(u, id + n), link(v, id + n);
        del.emplace_back(mr(id, -1));
    }
    return ;
}

void undo() {
    int id = del.back().fi, op = del.back().se;
    if(op == 1) {
        link(e2[id].u, e2[id].id + n), link(e2[id].v, e2[id].id + n);
    } 
    else {
        cut(e2[id].u, e2[id].id + n), cut(e2[id].v, e2[id].id + n);
    }
    del.pop_back(); return ;
}

void dele(int cnt) {
    while(del.size() > cnt) undo();
    return ;
}

void query(int p, int l, int r) {
    ll summ = sum; int cnt = del.size();
    for (int i : tr[p]) insert(i);
    if(l == r) {
        if(l <= q) printf("%lld\n", sum);
        sum = summ, dele(cnt);
        return ;
    }
    int mid = (l + r) >> 1;
    query(p << 1, l, mid), query(p << 1 | 1, mid + 1, r);
    sum = summ, dele(cnt);
    return ;
}

vector <pii> tim[N];

int main() {
    scanf("%d %d %d", &n, &m, &q);
    for (int i = 1; i <= m; ++i) {
        scanf("%d %d %d", &e1[i].u, &e1[i].v, &e1[i].w);
        tim[i].emplace_back(mr(e1[i].w, 1));
    }
    for (int i = 1; i <= q; ++i) {
        int k, d; scanf("%d %d", &k, &d);
        tim[k].emplace_back(mr(d, i));
    }
    int mm = 0;
    for (int i = 1; i <= m; ++i) {
        tim[i].emplace_back(mr(e1[i].w, q + 1));
        for (int j = 1; j < tim[i].size(); ++j) {
            int l = tim[i][j - 1].se, r = tim[i][j].se - 1;
            if(l <= r) {
                e2[++mm] = {e1[i].u, e1[i].v, tim[i][j - 1].fi, mm};
                val[mm + n] = mm;
                modify(1, 1, q + 1, l, r, mm);
            }
        }
    }
    m = mm;
    query(1, 1, q + 1);
    return 0;
}
2023/9/2 14:05
加载中...