小清新树剖求调悬关
查看原帖
小清新树剖求调悬关
651793
Rosent楼主2024/10/4 18:28

rt,调了两天了 qaq,样例能过但是 WA 0pts。

#include <bits/stdc++.h>
#define maxn 100010
#define int long long

#ifndef ONLINE_JUDGE
#define getchar_unlocked() getchar()
#endif

using namespace std;

int read() {
    int x=0,flag=1;char c=getchar_unlocked();
    while(c<'0'||c>'9') {if(c=='-')flag=-1;c=getchar_unlocked();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar_unlocked();}
    return x*flag;
}
struct edge {
    int next, to;
}e[maxn<<1];
int head[maxn], siz[maxn], dep[maxn], son[maxn], top[maxn], dfn[maxn], low[maxn], f[maxn], idx[maxn];
int n, m, cnt = 0, num = 0, cntc = 0;
void add(int u, int v) {
    e[++cnt].next = head[u];
    e[cnt].to = v;
    head[u] = cnt;
}
struct segment {
    int col[maxn<<2], rig[maxn<<2], lef[maxn<<2], cov[maxn<<2];
    void pushup(int k) {
        col[k] = col[k * 2] + col[k * 2 + 1];
        if (rig[k * 2] == lef[k * 2 + 1] && rig[k * 2] && lef[k * 2 + 1]) {
            col[k] ++;
        }
        rig[k] = rig[k * 2 + 1];
        lef[k] = lef[k * 2];
    }
    void cover(int k, int l, int r, int v) {
        col[k] = (r - l + 1) - 1;
        rig[k] = v;
        lef[k] = v;
        cov[k] = v;
    }
    void pushdown(int k, int l, int r) {
        if (cov[k]) {
            int mid = (l + r) / 2;
            cover(k * 2, l, mid, cov[k]);
            cover(k * 2 + 1, mid + 1, r, cov[k]);
            cov[k] = 0;
        }
    }
    void modify(int k, int l, int r, int x, int y, int v) {
        if (x <= l && r <= y) {
            cover(k, l, r, v);
            return ;
        }
        int mid = (l + r) / 2;
        pushdown(k, l, r);
        if (x <= mid) {
            modify(k * 2, l , mid, x, y, v);
        }
        if (y > mid) {
            modify(k * 2 + 1, mid + 1, r, x, y, v);
        }
        pushup(k);
    }
    int query(int k, int l, int r, int x, int y) {
        if (x <= l && r <= y) {
            return col[k];
        }
        int res = 0;
        int mid = (l + r) / 2;
        pushdown(k, l, r);
        if (x <= mid) {
            res += query(k * 2, l, mid, x, y);
        }
        if (y > mid) {
            res += query(k * 2 + 1, mid + 1, r, x, y);
        }
        pushup(k);
        return res;
    }
    int query2(int k, int p, int l, int r) {
        if (p == l) {
            return lef[k];
        }
        pushdown(k, l, r);
        int mid = (l + r) / 2;
        if (p <= mid) {
            return query2(k * 2, p, l, mid);
        }
        else {
            return query2(k * 2 + 1, p, mid + 1, r);
        }
    }
}st;

void dfs1(int u, int fa) {
    siz[u] = 1;
    dep[u] = dep[fa] + 1;
    f[u] = fa;
    for (int i = head[u]; i; i = e[i].next) {
        int to = e[i].to;
        if (to == fa) {
            continue;
        }
        dfs1(to, u);
        siz[u] += siz[to];
        if (siz[to] > siz[son[u]]) {
            son[u] = to;
        }
    }
}

void dfs2(int u, int fa, int htop) {
    dfn[u] = ++ num;
    top[u] = htop;
    idx[num] = u;
    if (son[u]) {
        dfs2(son[u], u, htop);
    }
    for (int i = head[u]; i; i = e[i].next) {
        int to = e[i].to;
        if (to == fa || to == son[u]) {
            continue;
        }
        dfs2(to, u, to);
    }
    low[u] = num;
}

void pathupd(int x, int y, int v) {
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) {
            swap(x, y);
        }
        st.modify(1, 1, n, dfn[top[x]], dfn[x],v);
        x = f[top[x]];
    }
    if (dep[x] < dep[y]) {
        swap(x, y);
    }
    st.modify(1, 1, n, dfn[y], dfn[x], v);
}

int pathqry(int x, int y) {
    int res = 0;
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) {
            swap(x, y);
        }
        res += st.query(1, 1, n, dfn[top[x]], dfn[x]);
        int col1 = st.query2(1, dfn[top[x]], 1, n);
        int col2 = st.query2(1, dfn[f[top[x]]], 1, n);
        if (col1 == col2 && col1 && col2) {
            res ++;
        }
        x = f[top[x]];
    }
    if (dep[x] < dep[y]) {
        swap(x, y);
    }
    res += st.query(1, 1, n, dfn[y], dfn[x]);
    return res;
}

void clear(int n) {
    for (int i = 1; i <= n; i++) {
        head[i] = siz[i] = dep[i] = son[i] = top[i] = dfn[i] = low[i] = idx[i] = f[i] = 0;
    }
    cnt = 0, num = 0, cntc = 0;
    memset(e, 0, sizeof(e));
    for (int i = 1; i <= 4 * n; i++) {
        st.col[i] = st.rig[i] = st.lef[i] = st.cov[i] = 0;
    }
}

signed main() {
    int T;
    T = read();
    while (T--) {
        n = read(), m = read();
        for (int i = 1; i < n; i++) {
            int u, v;
            u = read(), v = read();
            add(u, v); add(v, u);
        }
        dfs1(1, 0);
        dfs2(1, 0, 1);
        for (int i = 1; i <= m; i++) {
            int op, a, b;
            op = read(), a = read(), b = read();
            if (op == 1) {
                pathupd(a, b, ++cntc);
            }
            else if (op == 2) {
                cout << pathqry(a, b) << endl;
            }
        }
        clear(n);
    }
    return 0;
}

2024/10/4 18:28
加载中...