萌新求助点分治

P3806 【模板】点分治 1

Plozia @ 2021-05-06 19:58:27

RT,9 个点全部 WA。

照着这篇日报写的。

/*
========= Plozia =========
    Author:Plozia
    Problem:P3806 【模板】点分治1
    Date:2021/5/6
========= Plozia =========
*/

#include <bits/stdc++.h>

typedef long long LL;
const int MAXN = 1e4 + 10;
int n, m, Head[MAXN], cnt_Edge = 1, q[MAXN], root = 1, res[MAXN], f[MAXN], Size[MAXN], cnt, d[MAXN], total_node;
struct node { int to, val, Next; } Edge[MAXN << 1];
bool book[MAXN];

int read()
{
    int sum = 0, fh = 1; char ch = getchar();
    for (; ch < '0' || ch > '9'; ch = getchar()) fh -= (ch == '-') << 1;
    for (; ch >= '0' && ch <= '9'; ch = getchar()) sum = (sum << 3) + (sum << 1) + (ch ^ 48);
    return sum * fh;
}
void add_Edge(int x, int y, int z) { ++cnt_Edge; Edge[cnt_Edge] = (node){y, z, Head[x]}; Head[x] = cnt_Edge; }
int Max(int fir, int sec) { return (fir > sec) ? fir : sec; }

void Get_zx(int now, int father)
{
    f[now] = 0, Size[now] = 1;
    for (int i = Head[now]; i; i = Edge[i].Next)
    {
        int u = Edge[i].to;
        if (book[u] || u == father) continue ;
        Get_zx(u, now);
        f[now] = Max(f[now], Size[u]);
        Size[now] += Size[u];
    }
    f[now] = Max(f[now], total_node - f[now]);
    if (f[now] < f[root]) root = now;
}

void Get_dis(int now, int father, int dis)
{
    for (int i = Head[now]; i; i = Edge[i].Next)
    {
        int u = Edge[i].to;
        if (book[u] || u == father) continue ;
        ++cnt; d[cnt] = dis + Edge[i].val;
        Get_dis(u, now, d[cnt]);
    }
}

void Get_ans(int now, int dis, int Tag)
{
    cnt = 1; d[cnt] = dis;
    Get_dis(now, 0, dis);
    std::sort(d + 1, d + cnt + 1);
    for (int _ = 1; _ <= m; ++_)
    {
        int l = 1, r = cnt, ans = 0;
        while (l < r && d[l] + d[r] < q[_]) ++l;
        while (l < r)
        {
            ans += std::upper_bound(d + l, d + cnt + 1, q[_]) - std::lower_bound(d + l, d + cnt + 1, q[_]);
            ++l;
        }
        if (Tag == 0) res[_] += ans;
        else res[_] -= ans;
    }
}

void Solve(int now)
{
    book[now] = 1; Get_ans(now, 0, 0);
    for (int i = Head[now]; i; i = Edge[i].Next)
    {
        int u = Edge[i].to;
        if (book[u]) continue ;
        Get_ans(u, Edge[i].val, 1);
        total_node = Size[u]; root = 0;
        Get_zx(u, 0); Solve(root);
    }
}

int main()
{
    n = read(), m = read();
    for (int i = 1; i < n; ++i)
    {
        int x = read(), y = read(), z = read();
        add_Edge(x, y, z); add_Edge(y, x, z);
    }
    for (int i = 1; i <= m; ++i) q[i] = read();
    Get_zx(1, 0); Solve(root);
    for (int i = 1; i <= m; ++i)
        if (res[i]) printf("AYE\n");
        else printf("NAY\n");
    return 0;
}

|