萌新刚学OI,31pts,评测机上是WA,但自己下数据测是RE
查看原帖
萌新刚学OI,31pts,评测机上是WA,但自己下数据测是RE
486001
Knighthood楼主2022/11/27 19:15
//
// Created by Kcxx on 27/11/2022
//
#include<iostream>
#include<vector>

using namespace std;

const int N = 2e5 + 5;

vector<int> E[N];
int dep[N], p[N], fp[N], pos, top[N], sz[N], son[N], root, f[N];

void Dfs1(int u, int fa,int d) {
//    cerr << u << '\n';
    dep[u] = d;
    sz[u] = 1;
    for(auto v : E[u]) {
        if(v == fa)
            continue;
//        cerr << u << ' ' << v;
        f[v] = u;
        Dfs1(v, u, d + 1);
        sz[u] += sz[v];
        if(!son[u] || sz[son[u]] < sz[v])
            son[u] = v;
    }
}

void Dfs2(int u, int fa, int sp) {
    top[u] = sp;
    p[u] = ++pos;
    fp[pos] = u;
    if(son[u])
        Dfs2(son[u], u, sp);
    for(auto v : E[u]) {
        if(v == fa || v == son[u])
            continue;
        Dfs2(v, u, v);
    }
}

class Node {
public:
    int lc, rc, sum, lazy;
    Node() {
        lc = rc = sum = 0;
    }
};

class Segment_tree {
#define lc(k) t[k].lc
#define rc(k) t[k].rc
#define s(k) t[k].sum
#define z(k) t[k].lazy
#define middle(a, b)((a + b) >> 1)
private:
    int tot = 0;
    vector<Node> t;

    void up(int k) {
        s(k) = s(lc(k)) + s(rc(k));
    }

    void down(int k, int L, int R) {
        if(z(k)) {
            int mid = middle(L, R);
            z(lc(k)) += z(k);
            z(rc(k)) += z(k);
            s(lc(k)) += z(k) *(mid - L + 1);
            s(rc(k)) += z(k) *(R - mid);
            z(k) = 0;
        }
    }
public:
    explicit Segment_tree() = default;

    void Open(int n) {
        t.resize(2 * n + 14);
    }

    void Modify(int &k, int l, int r, int L, int R) {
        if(!k)
            k = ++tot;
        if(l <= L && R <= r) {
            ++s(k);
            ++z(k);
            return;
        }
        if(L == R)
            return;
        down(k, L, R);
        int mid = middle(L, R);
        if(l <= mid)
            Modify(lc(k), l, r, L, mid);
        if(r > mid)
            Modify(rc(k), l, r, mid + 1, R);
        up(k);
    }

    int Query(int k, int l, int r, int L, int R) {
        if(l <= L && R <= r)
            return s(k);
        if(L == R)
            return 0;
        down(k, L, R);
        int mid = middle(L, R);
        int ans = 0;
        if(lc(k) && l <= mid)
            ans += Query(lc(k), l, r, L, mid);
        if(rc(k) && r > mid)
            ans += Query(rc(k), l, r, mid + 1, R);
        return ans;
    }
}str;

template<typename T>
void swp(T &_1, T &_2) {
    _1 ^= _2, _2 ^= _1, _1 ^= _2;
}

void Tc_Modify(int u, int v) {
    int fu = top[u], fv = top[v];
    while(fu != fv) {
        if(dep[fu] < dep[fv])
            swp(u, v), swp(fu, fv);
        str.Modify(root, p[fu], p[u], 1, pos);
//        cout << fu << ' ' << u << '\n';
//        cout << p[fu] << ' ' << p[u] << '\n';
        u = f[fu];
        fu = top[u];
    }
    if(dep[u] < dep[v])
        swp(u, v);
//    cout << v << ' ' << u << '\n';
//    cout << p[v] << ' ' << p[u] << '\n';
    str.Modify(root, p[v] + 1, p[u], 1, pos);
}

int Tc_Query(int u, int v) {
    int ans = 0;
    int fu = top[u], fv = top[v];
    while(fu != fv) {
        if(dep[fu] < dep[fv])
            swp(u, v), swp(fu, fv);
        ans += str.Query(root, p[fu], p[u], 1, pos);
        u = f[fu];
        fu = top[u];
    }
    if(dep[u] < dep[v])
        swp(u, v);
    ans += str.Query(root, p[v] + 1, p[u], 1, pos);
    return ans;
}

int main() {
#ifdef LOCAL
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);

    int n, q;
    cin >> n >> q;
    for(int i = 1; i < n; ++i) {
        int u, v;
        cin >> u >> v;
        E[u].push_back(v);
        E[v].push_back(u);
    }
//    for(auto cs : E[6287])
//        cerr << cs << ' ';
//    cerr << '\n';

    Dfs1(1, 0, 1);
    cerr << pos << '\n';
    Dfs2(1, 0, 1);
    str.Open(pos);

    while(q--) {
        char op;
        int u, v;
        cin >> op >> u >> v;
        if(op == 'P')
            Tc_Modify(u, v);
        else
            cout << Tc_Query(u, v) << '\n';
    }

    return 0;
}
2022/11/27 19:15
加载中...