大常数线段树合并被卡了求助TLE
查看原帖
大常数线段树合并被卡了求助TLE
498612
Saka_Noa楼主2023/1/29 10:37
#include <bits/stdc++.h>
using namespace std;
#define _ (int)(5e5 + 5)
struct edge
{
    int next, to;
} e[_];
int head[_], cot;
void add(int f, int t)
{
    e[++cot] = (edge){head[f], t};
    head[f] = cot;
}
int root[_], val[_ * 20], lc[_ * 20], rc[_ * 20], cnt;
int n, m;
vector<pair<int, int>> QU[_];
int ans[_];
#define lcon lc[p], l, mid
#define rcon rc[p], mid + 1, r
#define Mid int mid = (l + r) >> 1
#define FR for (int i = head[u]; i; i = e[i].next)
int si[_], so[_], de[_], fa[_], to[_], se[_], re[_];
int maxdeep;
int Tree_Cnt;
int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0', ch = getchar();
    }
    return x * f;
}
void write(int x)
{
    if (x < 0)
    {
        putchar('-');
        x = -x;
    }
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
void dfs1(int u)
{
    de[u] = de[fa[u]] + 1;
    maxdeep = max(de[u], maxdeep);
    si[u] = 1;
    FR
    {
        int v = e[i].to;
        if (v == fa[u])
            continue;
        dfs1(v);
        si[u] += si[v];
        if (si[v] > si[so[u]])
            so[u] = v;
    }
}
void dfs2(int u, int tof)
{
    to[u] = tof;
    se[u] = ++Tree_Cnt;
    re[Tree_Cnt] = u;
    if (!so[u])
        return;
    dfs2(so[u], tof);
    FR
    {
        int v = e[i].to;
        if (v == fa[u] || v == so[u])
            continue;
        dfs2(v, v);
    }
}
int tree_lca(int x, int k)
{
    int fx = to[x];
    while ((se[x] - se[fx] + 1) < k)
    {
        k -= (se[x] - se[fx] + 1);
        x = fa[fx];
        fx = to[x];
    }
    x = re[se[x] - k + 1];
    return x;
}
void update(int &p, int l, int r, int x)
{
    if (!p)
        p = ++cnt;
    if (l == r)
    {
        val[p]++;
        return;
    }
    Mid;
    if (x <= mid)
        update(lcon, x);
    else
        update(rcon, x);
}
int query(int p, int l, int r, int x)
{
    if (!p)
        return 0;
    if (l == r)
        return val[p];
    Mid;
    if (x <= mid)
        return query(lcon, x);
    else
        return query(rcon, x);
}
int merge(int a, int b, int l, int r)
{
    if (!a || !b)
        return a + b;
    if (l == r)
    {
        val[a] += val[b];
        return a;
    }
    Mid;
    lc[a] = merge(lc[a], lc[b], l, mid);
    rc[a] = merge(rc[a], rc[b], mid + 1, r);
    return a;
}
void dfs(int u)
{
    FR
    {
        int v = e[i].to;
        if (v == fa[u])
            continue;
        dfs(v);
        root[u] = merge(root[u], root[v], 1, maxdeep);
    }
    if (u == 1)
        return; // ddd
    for (int j = 0; j < QU[u].size(); j++)
    {
        int id = QU[u][j].first, p = QU[u][j].second;
        ans[id] = query(root[u], 1, maxdeep, p + de[u]) - 1;
    }
    update(root[u], 1, maxdeep, de[u]);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    n = read();
    for (int i = 1; i <= n; i++)
    {
        int f;
        f = read();
        add(f + 1, i + 1);
        fa[i + 1] = f + 1;
    }
    dfs1(1);
    dfs2(1, 1);
    m = read();
    for (int i = 1; i <= m; i++)
    {
        int v, p;
        v = read(), p = read();
        v++;
        int fx = tree_lca(v, p + 1);
        QU[fx].push_back(make_pair(i, p));
    }
    dfs(1);
    for (int i = 1; i <= m; i++)
    {
        write(ans[i]);
        putchar(' ');
    }
    return 0;
}
2023/1/29 10:37
加载中...