求助关于开空间
查看原帖
求助关于开空间
388651
5k_sync_closer楼主2023/3/22 17:10

为什么我的倍增数组要开到 800050×20800050\times20 才能过?理论上不应该是 2n×logn2n\times\log n 吗?

#include <cstdio>
#include <algorithm>
using namespace std;
struct S
{
    int u, v, w;
} g[400050];
int n, m, q, o, P[400050];
bool C1(S a, S b) { return a.w > b.w; }
bool C2(S a, S b) { return a.w < b.w; }
struct Z
{
    int l = 0, r = 0, v = 0;
} R[30000050];
int M(int l, int s, int t, int d)
{
    int p = ++o;
    R[p] = R[d];
    ++R[p].v;
    if (s == t)
        return p;
    int m = s + t >> 1;
    if (l <= m)
        R[p].l = M(l, s, m, R[d].l);
    else
        R[p].r = M(l, m + 1, t, R[d].r);
    return p;
}
bool Q(int l, int r, int s, int t, int c, int d)
{
    if (l <= s && t <= r)
        return R[d].v - R[c].v;
    int m = s + t >> 1;
    bool q = 0;
    if (l <= m)
        q |= Q(l, r, s, m, R[c].l, R[d].l);
    if (r > m)
        q |= Q(l, r, m + 1, t, R[c].r, R[d].r);
    return q;
}
struct T
{
    struct E
    {
        int v, t;
    } e[400050];
    int c, p, a[400050], b[400050], k[400050], s[400050], f[400050], h[400050], t[800050][20]; //here
    void A(int u, int v)
    {
        e[++c] = {v, h[u]};
        h[u] = c;
    }
    int F(int x) { return x == f[x] ? x : f[x] = F(f[x]); }
    void D(int u)
    {
        s[k[b[u] = ++p] = u] = 1;
        for (int i = h[u], v; i; i = e[i].t)
        {
            t[v = e[i].v][0] = u;
            for (int j = 1; j <= __lg(n); ++j)
                t[v][j] = t[t[v][j - 1]][j - 1];
            D(v);
            s[u] += s[v];
        }
    }
    T()
    {
        for (int i = 1; i < n << 1; ++i)
            f[i] = i;
        for (int i = 0, o = n, U, V; i < m; ++i)
            if ((U = F(g[i].u)) != (V = F(g[i].v)))
                a[f[U] = f[V] = ++o] = g[i].w, A(o, U), A(o, V);
        D((n << 1) - 1);
    }
};
int main()
{
    scanf("%d%d%d", &n, &m, &q);
    for (int i = 0; i < m; ++i)
        scanf("%d%d", &g[i].u, &g[i].v), g[i].w = min(++g[i].u, ++g[i].v);
    sort(g, g + m, C1);
    T A;
    for (int i = 0; i < m; ++i)
        g[i].w = max(g[i].u, g[i].v);
    sort(g, g + m, C2);
    T B;
    for (int i = 1; i < n << 1; ++i)
        P[i] = A.k[i] <= n ? M(B.b[A.k[i]], 1, (n << 1) - 1, P[i - 1]) : P[i - 1];
    for (int i = 0, u, v, l, r; i < q; ++i)
    {
        scanf("%d%d%d%d", &u, &v, &l, &r);
        ++u;
        ++v;
        ++l;
        ++r;
        for (int j = __lg(n); j >= 0; --j)
            if (A.t[u][j] && A.a[A.t[u][j]] >= l)
                u = A.t[u][j];
        for (int j = __lg(n); j >= 0; --j)
            if (B.t[v][j] && B.a[B.t[v][j]] <= r)
                v = B.t[v][j];
        printf("%d\n", Q(B.b[v], B.b[v] + B.s[v] - 1, 1, (n << 1) - 1, P[A.b[u] - 1], P[A.b[u] + A.s[u] - 1]));
    }
    return 0;
}
2023/3/22 17:10
加载中...