QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#192305#7513. Palindromic Beadsucup-team1198#WA 3ms32000kbC++207.4kb2023-09-30 14:11:512023-09-30 14:11:52

Judging History

你现在查看的是最新测评结果

  • [2024-03-27 16:34:54]
  • hack成功,自动添加数据
  • (/hack/584)
  • [2024-03-27 16:18:45]
  • hack成功,自动添加数据
  • (/hack/583)
  • [2023-09-30 14:11:52]
  • 评测
  • 测评结果:WA
  • 用时:3ms
  • 内存:32000kb
  • [2023-09-30 14:11:51]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;
#define ll long long
#define pii pair<int, int>
#define ld long double
#define all(a) (a).begin(), (a).end()

const int MAXN = 200'200;
const int K = 18;

vector<int> G[MAXN];
int depth[MAXN];
int up[MAXN][K];
int tin[MAXN];
int tout[MAXN];
int ttime = 0;

void dfs(int v, int p, int w) {
    depth[v] = w;
    up[v][0] = p;
    tin[v] = ttime;
    ++ttime;
    for (int u : G[v]) {
        if (u == p)
            continue;
        dfs(u, v, w + 1);
    }
    tout[v] = ttime;
    ++ttime;
}

int la(int v, int d) {
    for (int k = K - 1; k >= 0; --k) {
        if (d >= (1 << k)) {
            v = up[v][k];
            d -= 1 << k;
        }
    }
    return v;
}

int lca(int v, int u) {
    if (depth[v] > depth[u])
        v = la(v, depth[v] - depth[u]);
    else
        u = la(u, depth[u] - depth[v]);
    if (v == u)
        return v;
    for (int k = K - 1; k >= 0; --k) {
        if (up[v][k] != up[u][k]) {
            v = up[v][k];
            u = up[u][k];
        }
    }
    return up[v][0];
}

int couple[MAXN];

vector<int> extra_vertices[MAXN];
vector<int> extra_vertices_on_up_edge[MAXN];

vector<int> G2[MAXN];

vector<int> tin_order;
int tin2[MAXN];
int tout2[MAXN];

void dfs2(int v, int p) {
    tin2[v] = tin_order.size();
    tin_order.emplace_back(v);
    for (int u : G2[v]) {
        if (u == p)
            continue;
        dfs2(u, v);
    }
    tout2[v] = tin_order.size();
}

int val[(1 << 19) + 228];
int mod[(1 << 19) + 228];

void build(int v, int left, int right) {
    val[v] = 0;
    mod[v] = 0;
    if (left + 1 == right)
        return;
    int mid = (left + right) / 2;
    build(2 * v + 1, left, mid);
    build(2 * v + 2, mid, right);
}

int get(int v, int left, int right, int x, int y) {
    if (y <= left || right <= x)
        return -1e9;
    if (x <= left && right <= y)
        return val[v];
    int mid = (left + right) / 2;
    return max(get(2 * v + 1, left, mid, x, y), get(2 * v + 2, mid, right, x, y)) + mod[v];
}

void add(int v, int left, int right, int x, int y, int d) {
    if (y <= left || right <= x)
        return;
    if (x <= left && right <= y) {
        mod[v] += d;
        val[v] += d;
        return;
    }
    int mid = (left + right) / 2;
    add(2 * v + 1, left, mid, x, y, d);
    add(2 * v + 2, mid, right, x, y, d);
    val[v] = max(val[2 * v + 1], val[2 * v + 2]) + mod[v];
}

int n;
int ans = 0;

void dfs3(int v, int p) {
    if (couple[v] != -1) {
        add(0, 0, n, tin2[couple[v]], tout2[couple[v]], 1);
    }
    ans = max(ans, get(0, 0, n, 0, n));
    for (int u : G2[v]) {
        if (u == p)
            continue;
        dfs3(u, v);
    }
    if (couple[v] != -1) {
        add(0, 0, n, tin2[couple[v]], tout2[couple[v]], -1);
    }
}


signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n;
    vector<int> c(n);
    for (int i = 0; i < n; ++i)
        cin >> c[i];
    for (int i = 1; i < n; ++i) {
        int a, b;
        cin >> a >> b;
        G[a - 1].emplace_back(b - 1);
        G[b - 1].emplace_back(a - 1);
    }
    dfs(0, 0, 0);
    for (int j = 1; j < K; ++j) {
        for (int i = 0; i < n; ++i) {
            up[i][j] = up[up[i][j - 1]][j - 1];
        }
    }
    fill(couple, couple + n, -1);
    vector<int> prev_id(n, -1);
    for (int i = 0; i < n; ++i) {
        --c[i];
        if (prev_id[c[i]] == -1) {
            prev_id[c[i]] = i;
        } else {
            int j = prev_id[c[i]];

            int l = lca(i, j);
            int len = depth[i] + depth[j] - 2 * depth[l];
            if (len % 2 == 0) {
                int len2 = len / 2;
                int mid = l;
                if (depth[i] - depth[l] >= len2)
                    mid = la(i, len2);
                else
                    mid = la(j, len2);
                extra_vertices[mid].emplace_back(i);
                extra_vertices[mid].emplace_back(j);
            } else {
                int len2 = len / 2;
                int mid = l;
                if (depth[i] - depth[l] >= len2 + 1)
                    mid = la(i, len2);
                else
                    mid = la(j, len2);
                extra_vertices_on_up_edge[mid].emplace_back(i);
                extra_vertices_on_up_edge[mid].emplace_back(j);
            }
        }
    }
    build(0, 0, n);
    int real_ans = 1;
    for (int root = 0; root < n; ++root) {
        if (extra_vertices[root].empty())
            continue;
        for (int i = 0; i < extra_vertices[root].size(); ++i) {
            couple[extra_vertices[root][i]] = extra_vertices[root][i ^ 1];
        }
        vector<int> order;
        swap(order, extra_vertices[root]);
        order.emplace_back(root);
        sort(order.begin(), order.end(), [](int a, int b) {
            return tin[a] < tin[b];
        });
        int len = order.size();
        for (int i = 0; i + 1 < len; ++i) {
            order.emplace_back(lca(order[i], order[i + 1]));
        }
        sort(order.begin(), order.end(), [](int a, int b) {
            return tin[a] < tin[b];
        });
        order.resize(unique(order.begin(), order.end()) - order.begin());
        vector<int> stack;
        for (int v : order) {
            while (!stack.empty() && tout[stack.back()] < tin[v]) {
                stack.pop_back();
            }
            if (!stack.empty()) {
                G2[stack.back()].emplace_back(v);
                G2[v].emplace_back(stack.back());
            }
            stack.emplace_back(v);
        }
        dfs2(root, -1);
        dfs3(root, -1);
        tin_order.clear();
        for (int v : order)
            G2[v].clear();
        for (int v : order)
            couple[v] = -1;
    }
    real_ans = max(real_ans, 2 * ans + 1);
    for (int root = 0; root < n; ++root) {
        if (extra_vertices_on_up_edge[root].empty())
            continue;
        ans = 0;
        for (int i = 0; i < extra_vertices_on_up_edge[root].size(); ++i) {
            couple[extra_vertices_on_up_edge[root][i]] = extra_vertices_on_up_edge[root][i ^ 1];
        }
        bool flag = false;
        if (couple[root] != -1) {
            flag = true;
            couple[couple[root]] = -1;
            couple[root] = -1;
        }
        vector<int> order;
        swap(order, extra_vertices_on_up_edge[root]);
        
        order.emplace_back(root);
        order.emplace_back(up[root][0]);
        sort(order.begin(), order.end(), [](int a, int b) {
            return tin[a] < tin[b];
        });
        int len = order.size();
        for (int i = 0; i + 1 < len; ++i) {
            order.emplace_back(lca(order[i], order[i + 1]));
        }
        sort(order.begin(), order.end(), [](int a, int b) {
            return tin[a] < tin[b];
        });
        order.resize(unique(order.begin(), order.end()) - order.begin());
        vector<int> stack;
        for (int v : order) {
            while (!stack.empty() && tout[stack.back()] < tin[v]) {
                stack.pop_back();
            }
            if (!stack.empty()) {
                G2[stack.back()].emplace_back(v);
                G2[v].emplace_back(stack.back());
            }
            stack.emplace_back(v);
        }
        dfs2(root, -1);
        dfs3(root, -1);
        tin_order.clear();
        for (int v : order)
            G2[v].clear();
        for (int v : order)
            couple[v] = -1;
        if (flag)
            real_ans = max(real_ans, 2 * ans + 2);
    }
    cout << real_ans << '\n';

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 32000kb

input:

4
1 1 2 2
1 2
2 3
2 4

output:

3

result:

ok single line: '3'

Test #2:

score: -100
Wrong Answer
time: 3ms
memory: 29056kb

input:

5
1 3 2 2 1
1 2
2 3
3 4
4 5

output:

3

result:

wrong answer 1st lines differ - expected: '4', found: '3'