求助wa4
查看原帖
求助wa4
432356
涼風青葉楼主2022/12/15 12:10
#include<iostream>
#include<queue>
#include<vector>

using namespace std;

constexpr int N = 1e5 + 10;
int n, m;

namespace
{
    int tot;
    vector<int> h[N];
    bool book[N], light[N];
    int fa[N];
    struct Parent
    {
        int root, dist;
    };
    vector<Parent> parent[N];
    priority_queue<int> dist1[N], erase_dist1[N], dist2[N], erase_dist2[N], all, erase_all;

    int get_size(int u, int p)
    {
        if (book[u])
            return 0;

        int sum = 1;
        for (auto sn : h[u])
        {
            if (sn == p)
                continue;
            sum += get_size(sn, u);
        }

        return sum;
    }

    int get_wc(int u, int p, int tot, int &wc)
    {
        if (book[u])
            return 0;

        int sum = 1, ms = 0;
        for (auto sn : h[u])
        {
            if (sn == p)
                continue;

            int t = get_wc(sn, u, tot, wc);
            sum += t;
            ms = max(ms, t);
        }

        ms = max(ms, tot - sum);
        if (ms <= tot >> 1)
            wc = u;
        return sum;
    }

    void get_dist(int u, int p, int root, int dist)
    {
        if (book[u])
            return;

        parent[u].push_back({ root, dist });

        for (auto sn : h[u])
        {
            if (sn == p)
                continue;
            get_dist(sn, u, root, dist + 1);
        }
    }

    void calc(int u, int p)
    {
        if (book[u])
            return;

        get_wc(u, 0, get_size(u, 0), u);
        book[u] = true;
        fa[u] = p;

        for (auto sn : h[u])
        {
            int t;
            get_wc(sn, 0, get_size(sn, 0), t);
            get_dist(sn, 0, t, 1);
        }

        for (auto sn : h[u])
            calc(sn, u);
    }

    void add_res(int k)
    {
        auto &d1 = dist1[k], &ed1 = erase_dist1[k];

        while (d1.size() && ed1.size() && d1.top() == ed1.top())
            d1.pop(), ed1.pop();
        if (d1.size())
        {
            int t = d1.top();
            d1.pop();

            while (d1.size() && ed1.size() && d1.top() == ed1.top())
                d1.pop(), ed1.pop();
            if (d1.size())
            {
                all.push(d1.top() + t);
                d1.push(t);
            }
        }
    }

    void rem_res(int k)
    {
        auto &d1 = dist1[k], &ed1 = erase_dist1[k];

        while (d1.size() && ed1.size() && d1.top() == ed1.top())
            d1.pop(), ed1.pop();
        if (d1.size())
        {
            int t = d1.top();
            d1.pop();

            while (d1.size() && ed1.size() && d1.top() == ed1.top())
                d1.pop(), ed1.pop();
            if (d1.size())
            {
                erase_all.push(d1.top() + t);
                d1.push(t);
            }
        }
    }

    void update(int k)
    {
        light[k] ^= 1;

        if (light[k])
        {
            tot--;

            for (auto &p : parent[k])
            {
                int root = p.root, dist = p.dist, f = fa[root];
                if (f)
                {
                    auto &d1 = dist1[f], &ed1 = erase_dist1[f];
                    auto &d2 = dist2[root], &ed2 = erase_dist2[root];

                    rem_res(f);
                    if (d2.size())
                        ed1.push(d2.top());

                    ed2.push(dist);
                    while (d2.size() && ed2.size() && d2.top() == ed2.top())
                        d2.pop(), ed2.pop();
                    if (d2.size())
                        d1.push(d2.top());

                    add_res(f);
                }

                auto &d1 = dist1[root], &ed1 = erase_dist1[root];

                rem_res(root);
                ed1.push(0);
                add_res(root);
            }
        }
        else
        {
            tot++;

            for (auto &p : parent[k])
            {
                int root = p.root, dist = p.dist, f = fa[root];
                if (f)
                {
                    auto &d1 = dist1[f], &ed1 = erase_dist1[f];
                    auto &d2 = dist2[root], &ed2 = erase_dist2[root];

                    rem_res(f);
                    if (d2.size())
                        ed1.push(d2.top());

                    d2.push(dist);
                    while (d2.size() && ed2.size() && d2.top() == ed2.top())
                        d2.pop(), ed2.pop();
                    if (d2.size())
                        d1.push(d2.top());

                    add_res(f);
                }

                auto &d1 = dist1[root], &ed1 = erase_dist1[root];

                rem_res(root);
                d1.push(0);
                add_res(root);
            }
        }
    }

    void solve()
    {
        calc(1, 0);

        for (int i = 1; i <= n; i++)
            for (auto &p : parent[i])
                dist2[p.root].push(p.dist);
        for (int i = 1; i <= n; i++)
            if (fa[i] && dist2[i].top())
                dist1[fa[i]].push(dist2[i].top());
        for (int i = 1; i <= n; i++)
        {
            dist1[i].push(0);
            add_res(i);
        }

        tot = n;
        for (int i = 1; i <= m; i++)
        {
            char op;

            cin >> op;
            if (op == 'C')
            {
                int k;
                cin >> k;

                update(k);
            }
            else
            {
                if (tot == 1)
                    cout << "0\n";
                else if (tot == 0)
                    cout << "-1\n";
                else
                {
                    while (all.size() && erase_all.size() && all.top() == erase_all.top())
                        all.pop(), erase_all.pop();
                    cout << all.top() << "\n";
                }
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> n;
    for (int i = 1; i < n; i++)
    {
        int a, b;
        cin >> a >> b;
        h[a].push_back(b);
        h[b].push_back(a);
    }
    cin >> m;

    solve();
}
2022/12/15 12:10
加载中...