过了样例,这也能WA?树上莫队调3小时,MNZN玄关求调
查看原帖
过了样例,这也能WA?树上莫队调3小时,MNZN玄关求调
22716
神仙酱楼主2024/3/26 16:44
#include <iostream>
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cmath>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int c[N], b[N], ans[N], bsz, now, cnt[N];
int e[N << 1], nxt[N << 1], h[N], idx = 1;
int dep[N], dfsq[N << 1], fa[N][22], in[N << 1], out[N << 1], dfn;
bool vis[N << 1];

void add(int a, int b)
{
    e[idx] = b, nxt[idx] = h[a], h[a] = idx++;
}

void dfs(int u, int pa)
{
    dfsq[in[u] = ++dfn] = u;
    dep[u] = dep[pa] + 1, fa[u][0] = pa;
    for (int i = h[u]; i; i = nxt[i])
        if (e[i] != pa)
            dfs(e[i], u);
    dfsq[out[u] = ++dfn] = u;
}

int lca(int x, int y)
{
    if (dep[x] > dep[y])
        swap(x, y);
    for (int i = 20; i >= 0; i--)
    {
        if (dep[y] - (i << i) > dep[x])
            y = fa[y][i];
    }
    if (x == y)
        return x;
    for (int i = 20; i >= 0; i--)
        if (fa[x][i] != fa[y][i])
            x = fa[x][i], y = fa[y][i];
    return fa[x][0];
}

struct query_t
{
    int id, l, r, ca;
    bool operator<(const query_t &rhs) const
    {
        if (l / bsz != rhs.l / bsz)
            return l < rhs.l;
        return (l / bsz) & 1 ? r < rhs.r : r > rhs.r;
    }
} q[N];

void add(int x)
{
    if (vis[x])
        now -= !--cnt[c[x]];
    else
        now += !cnt[c[x]]++;
    vis[x] ^= 1;
}

inline int read()
{
    int x{}, flag = 1;
    char ch = getchar();
    for (; !isdigit(ch); ch = getchar())
        if (ch == '-')
            flag = -1;
    for (; isdigit(ch); ch = getchar())
        x = x * 10 + (ch ^ 48);
    return x * flag;
}

signed main()
{
#ifndef ONLINE_JUDGE
    freopen(".in", "r", stdin);
    // freopen(".out", "w", stdout);
#else
    ios::sync_with_stdio(0);
#endif
    int n = read(), m = read();
    bsz = sqrt(n << 1);

    for (int i = 1; i <= n; ++i)
        b[i] = c[i] = read();
    sort(b + 1, b + 1 + n);
    int *end = unique(b + 1, b + 1 + n);
    for (int i = 1; i <= n; ++i)
        c[i] = lower_bound(b + 1, end, c[i]) - b;
    for (int i = 1; i < n; ++i)
    {
        int x = read(), y = read();
        add(x, y), add(y, x);
    }

    dfs(1, 0);
    for (int j = 1; j <= 20; ++j)
        for (int i = 1; i <= n; ++i)
            fa[i][j] = fa[fa[i][j - 1]][j - 1];

    int qcnt = 0;
    while (m--)
    {
        int l = read(), r = read();
        if (in[l] > in[r])
            swap(l, r);
        int ca = lca(l, r);
        q[++qcnt].r = in[r];
        if (ca == l)
            q[qcnt].l = in[l];
        else
            q[qcnt].l = out[l], q[qcnt].ca = ca;
        q[qcnt].id = qcnt;
    }
    sort(q + 1, q + 1 + qcnt);

    int l = 1, r = 0;
    for (int i = 1; i <= qcnt; ++i)
    {
        while (r < q[i].r)
            add(dfsq[++r]);
        while (l > q[i].l)
            add(dfsq[--l]);
        while (r > q[i].r)
            add(dfsq[r--]);
        while (l < q[i].l)
            add(dfsq[l++]);
        if (q[i].ca)
            add(q[i].ca);
        ans[q[i].id] = now;
        if (q[i].ca)
            add(q[i].ca);
    }
    for (int i = 1; i <= qcnt; ++i)
        printf("%lld\n", ans[i]);
}
2024/3/26 16:44
加载中...