被卡常了求条
查看原帖
被卡常了求条
340732
xinlin楼主2025/8/2 21:13

复杂度就是 O(qlogn)O(qlogn) 但由于人比较傻,常数特别大,导致第二个点就 TLE。希望有大佬帮忙卡下常。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <utility>
/*
开始写:
2025.8.2 15:35
开始调试时间:
2025.8.2 17:35:
1. pair没写<int, int> 
2. New函数没返回 
3. update加了参数忘记传递
4. 忘判了 {-1, 1} 
5. long long - > MLE
6. 更新的时候 false - > true 
7. q + 1个颜色 
8. Tc2初始时 update 
9. st表范围初始值 
10. long long 没改完 
11. dep 和 dis 混淆 
*/
const int N = 500015, M = 500015, LGn = 20;
int LG2[N];
int n, q, C;
struct Graph {
    struct edge{
        int u, v, w;
        int nxt;
    };
    edge edges[M];
    int head[N], cnt = 0;
    int fa[N], dfn_st[N], id[N], tim;
    int dep[N];
    long long Dis[N];
	int st[N][LGn];
    void add(int u, int v, int w) {
        edges[++cnt] = edge{u, v, w, head[u]};
        head[u] = cnt;
    }
    void clear() {
        memset(head, 0, sizeof(head));
        cnt = 0; tim = 0;
    }   
    void dfs(int x, int f, long long dist, int depth) {
        fa[x] = f; dep[x] = depth; Dis[x] = dist;
        id[x] = ++tim;
        dfn_st[tim] = x;
        for(int i = head[x]; i; i = edges[i].nxt) {
            int to = edges[i].v;
            if(to == f) continue;
            dfs(to, x, dist + edges[i].w, depth + 1);
        }
    }
    int dep_min(int x, int y) {
        if(dep[x] < dep[y]) return x;
        else return y;
    }
    void init_LCA() {
        dfs(1, 0, 0, 1);
        for(int i = 1; i <= n; ++i) st[i][0] = dfn_st[i];
        
        for(int i = 1; (1 << i) <= n; ++i) {
            for(int j = 1; j + (1 << i) - 1 <= n; ++j) {
                st[j][i] = dep_min(st[j][i - 1], st[j + (1 << (i - 1))][i - 1]);
            }
        }
        return;
    }
    int LCA(int x, int y) {
        if(x == y) return x;
        x = id[x], y = id[y];
        if(x > y) std::swap(x, y);
        ++x;
        int len = LG2[y - x + 1];
        return fa[
            dep_min(
                st[x][len],
                st[y - (1 << len) + 1][len]
            )   
        ];
    }
    long long dis(int x, int y) {
        return Dis[x] + Dis[y] - 2 * Dis[LCA(x, y)];
    }
}G;


struct Query{
    int tp;
    int x, c, d;
    int num;
}Q[N];
struct node_c{
    int lson, rson;
    std::pair<int, int> u;
    node_c() {
        lson = rson = 0;
        u = std::make_pair(-1, -1);
    }
};

node_c nodes_c[N * LGn * 2];
int ind = 0, root[N];
inline std::pair<int, int> Max(std::pair<int, int> a, std::pair<int, int> b) {
	bool ma, mb;
	ma = (a.first == -1) || (a.second == -1);
	mb = (b.first == -1) || (b.second == -1);
    if(ma && mb) return std::make_pair(-1, -1);
    else if(ma) return b;
    else if(mb) return a;
    
    if(G.dis(a.first, a.second) > G.dis(b.first, b.second)) return a;
    else return b;
}
struct Seg_tree_C{
    inline int New() {
        ++ind;
        nodes_c[ind] = node_c();
        return ind;
    }
    void update(int k, bool del, int x, int l = 1, int r = n) {
        if(l == r) {
            if(del)
                nodes_c[x].u = std::make_pair(-1, -1);
            else   
                nodes_c[x].u = std::make_pair(k, k);
            return;
        }
        int mid = (l + r) / 2;
        if(k <= mid) {
            if(nodes_c[x].lson == 0) 
                nodes_c[x].lson = New();
            update(k, del, nodes_c[x].lson, l, mid);
        }
        else {
            if(nodes_c[x].rson == 0) 
                nodes_c[x].rson = New();
            update(k, del, nodes_c[x].rson, mid + 1, r);
        }
        std::pair<int, int> v1 = nodes_c[nodes_c[x].lson].u,
        v2 = nodes_c[nodes_c[x].rson].u;
        nodes_c[x].u = Max(
            Max(std::pair<int, int>{v1.first, v2.first}, 
            std::pair<int, int>{v1.first, v2.second}), 
            Max(std::pair<int, int>{v1.second, v2.first}, 
            std::pair<int, int>{v1.second, v2.second})
        );
        nodes_c[x].u = Max(
            nodes_c[x].u,
            Max(v1, v2)
        );
    }
    std::pair<int, int> query(int x) {
        return nodes_c[root[x]].u;
    }
}Tc; //Tree_color

struct Seg_Tree_C2
{
    struct node_c2 {
        std::pair<int, int> far, nsa_far;
        node_c2() {
            far = std::pair<int, int>{-1, -1};
            nsa_far = std::pair<int, int>{-1, -1};
        }
    };   
    node_c2 T2[N << 2];
    void clear(int x, int l, int r) {
        T2[x] = node_c2();
        if(l == r) return;
        int mid = (l + r) / 2;
        node_c2 &lson = T2[x << 1];
        node_c2 &rson = T2[(x << 1) + 1];
//        if(!(lson.far.first == -1 && lson.far.second == -1)) 
		clear(x << 1, l, mid);
//        if(!(lson.far.first == -1 && lson.far.second == -1)) 
		clear((x << 1) + 1, mid + 1, r);
        return;
    }
    void update(int k, int x = 1, int l = 1, int r = q + 1) {
        if(l == r) {
            T2[x].nsa_far = std::make_pair(-1, -1);
            T2[x].far = Tc.query(l);
            return;
        }
        int mid = (l + r) / 2;
        if(k <= mid) update(k, (x << 1), l, mid);
        if(k > mid) update(k, (x << 1) + 1, mid + 1, r);
        auto u1 = T2[x << 1].far, v1 = T2[x << 1].nsa_far,
        u2 = T2[(x << 1) + 1].far, v2 = T2[(x << 1) + 1].nsa_far;
        T2[x].far = Max(
            Max(u1, u2),
            Max(
                Max(std::pair<int, int>{u1.first, u2.first}, 
                std::pair<int, int>{u1.first, u2.second}), 
                Max(std::pair<int, int>{u1.second, u2.first}, 
                std::pair<int, int>{u1.second, u2.second})
            )
        );
        T2[x].nsa_far = Max(
            Max(v1, v2),
            Max(
                Max(std::pair<int, int>{u1.first, u2.first}, 
                std::pair<int, int>{u1.first, u2.second}), 
                Max(std::pair<int, int>{u1.second, u2.first}, 
                std::pair<int, int>{u1.second, u2.second})
            )
        );
    }
    long long query() {
        auto u = T2[1].nsa_far;
        if(u.first == -1 || u.second == -1) return 0;
        return G.dis(u.first, u.second);
    }
}Tc2;
int Color[N];
void init() {
    ind = 0;
    memset(Color, 0, sizeof(Color));
    G.clear();
}
inline int read() {
	int s = 0;
	char c = getchar();
	while(c < '0' || c > '9') c = getchar();
	while(c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
	return s;
}
void solve(){
//	printf("NEW test \n"); 
    init();
//    scanf("%d%d", &q, &C);
	q = read(); C = read();
    n = 1;
    for(int i = 1; i <= q; ++i) {
        int tp, x, c, d;
//        scanf("%d", &tp);
		tp = read();
        if(tp == 0) {
//            scanf("%d%d%d", &x, &c, &d);
			x = read(); c = read(); d = read();
            ++n; 
            Q[i] = Query{tp, x, c, d, n};
            G.add(x, n, d);
        }
        else {
//            scanf("%d%d", &x, &c);
			x = read(); c = read();
            Q[i] = Query{tp, x, c, 0, x};
        }
    }
    for(int i = 1; i <= q + 1; ++i) 
		root[i] = Tc.New();
    G.init_LCA();
    Tc2.clear(1, 1, q + 1);
    
    Color[1] = C;
    Tc.update(1, false, root[C]);
    Tc2.update(C);
//    printf("dis %d %d = %lld\n", 5, 3, G.dis(5, 3));
    for(int i = 1; i <= q; ++i) {
        if(Q[i].tp == 0) {
            Tc.update(Q[i].num, false, Q[i].c);
            Tc2.update(Q[i].c);
            Color[Q[i].num] = Q[i].c;
        }
        else {
            Tc.update(Q[i].num, true, root[Color[Q[i].num]]);
            Tc.update(Q[i].num, false, root[Q[i].c]);
            Tc2.update(Color[Q[i].num]);
            Tc2.update(Q[i].c);
            Color[Q[i].num] = Q[i].c;
        }
        printf("%lld\n", Tc2.query());
//        if(i % 10000 == 0)
    }
//    while(1) {
//        int x, y;
//        scanf("%d%d", &x, &y);
//        printf("%d\n", G.dis(x, y));
//    }
}
void initLg2() {
    LG2[1] = 0;
    for(int i = 2; i < N; ++i) 
        LG2[i] = LG2[i >> 1] + 1;
    return;
}
int main(){
//	freopen("dat.in", "r", stdin); 
//	freopen("my.out", "w", stdout); 	
    initLg2();
     int t;
     scanf("%d", &t);
     while(t--)
         solve();
    return 0;
}
/*
1
14 1
0 1 3 9
*/
2025/8/2 21:13
加载中...