神秘复杂度过题了
查看原帖
神秘复杂度过题了
388651
5k_sync_closer楼主2023/3/24 11:05

大概是 O(Vmnw)O(\dfrac{Vm\sqrt n}w) ?要不要再乘个 log\log 我不确定,因为树剖下来的区间是不交的。

就是直接树剖套分块,维护块内 bitset,然后散块暴力,整块直接或起来。

感觉这个复杂度很难绷,但是没卡就过了?建议加强数据。

#include <cmath>
#include <cstdio>
#include <bitset>
using namespace std;
struct E
{
    int v, t;
} e[200050];
int n, m, c, p, K, L[512], R[512], T[100050], a[100050], z[100050],
    d[100050], f[100050], s[100050], t[100050], b[100050], k[100050], h[100050];
bitset<30001> B[512];
bool F;
void A(int u, int v)
{
    e[++c] = {v, h[u]};
    h[u] = c;
}
void X(int u)
{
    s[u] = 1;
    for (int i = h[u], v; i; i = e[i].t)
        if (!d[v = e[i].v])
        {
            d[v] = d[f[v] = u] + 1;
            X(v);
            s[u] += s[v];
            if (s[v] > s[z[u]])
                z[u] = v;
        }
}
void Y(int u, int g)
{
    t[k[b[u] = ++p] = u] = g;
    if (z[u])
        Y(z[u], g);
    for (int i = h[u], v; i; i = e[i].t)
        if ((v = e[i].v) != f[u] && v != z[u])
            Y(v, v);
}
bitset<30001> Q(int l, int r)
{
    bitset<30001> q;
    if (T[l] == T[r])
    {
        for (int i = l; i <= r; ++i)
            q[a[k[i]]] = 1;
        return q;
    }
    for (int i = l; i <= R[T[l]]; ++i)
        q[a[k[i]]] = 1;
    for (int i = T[l] + 1; i < T[r]; ++i)
        q |= B[i];
    for (int i = L[T[r]]; i <= r; ++i)
        q[a[k[i]]] = 1;
    return q;
}
int main()
{
    scanf("%d%d%d", &n, &m, &F);
    K = sqrt(n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", a + i);
    for (int i = 1, u, v; i < n; ++i)
        scanf("%d%d", &u, &v), A(u, v), A(v, u);
    X(d[1] = 1);
    Y(1, 1);
    for (int i = 1; i <= n; ++i)
        B[T[i] = (i - 1) / K + 1][a[k[i]]] = 1;
    for (int i = 1; i <= T[n]; ++i)
        L[i] = (i - 1) * K + 1, R[i] = min(i * K, n);
    for (int i = 0, l = 0, r, o, x, y; i < m; ++i)
    {
        bitset<30001> q;
        scanf("%d", &o);
        while (o--)
        {
            scanf("%d%d", &x, &y);
            if (F)
                x ^= l, y ^= l;
            while (t[x] != t[y])
            {
                if (d[t[x]] < d[t[y]])
                    swap(x, y);
                q |= Q(b[t[x]], b[x]);
                x = f[t[x]];
            }
            if (b[x] > b[y])
                swap(x, y);
            q |= Q(b[x], b[y]);
        }
        printf("%d %d\n", l = q.count(), r = (~q)._Find_first());
        l += r;
    }
    return 0;
}
2023/3/24 11:05
加载中...