为什么 WA 成了 6 分?

P3899 [湖南集训] 更为厉害

cancan123456 @ 2022-05-10 06:53:08

离线,然后树状数组二维数点。

#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 300000;
struct Edge {
    int v, next;
} edge[2 * N];
int head[N];
int cnt;
void add_edge(int u, int v) {
    cnt++;
    edge[cnt].v = v;
    edge[cnt].next = head[u];
    head[u] = cnt;
}
int dfn[N], dfncnt, size[N], dep[N];
void dfs(int u, int fa) {
    size[u] = 1;
    dfn[u] = ++dfncnt;
    for (int v, i = head[u]; i != 0; i = edge[i].next) {
        v = edge[i].v;
        if (v != fa) {
            dep[v] = dep[u] + 1;
            dfs(v, u);
            size[u] += size[v];
        }
    }
}
int n;
int c[N];
int lowbit(int x) {
    return x & - x;
}
void add(int x, int v) {
    if (x == 0) {
        c[x] += v;
    } else {
        while (x <= n) {
            c[x] += v;
            x += lowbit(x);
        }
    }
}
int query(int x) {
    int v = 0;
    while (x > 0) {
        v += c[x];
        x -= lowbit(x);
    }
    return v + c[0];
}
struct Point {
    int x, y, w;
} point[N];
bool operator < (const Point & a, const Point & b) {
    return a.y < b.y;
}
struct Query {
    int x, y1, y2, id;
} q[2 * N];
int qcnt;
bool operator < (const Query & a, const Query & b) {
    return a.x < b.x;
}
int ans[N];
int min(int a, int b) {
    return a < b ? a : b;
}
signed main() {
    int m;
    scanf("%d %d", &n, &m);
    for (int u, v, i = 1; i < n; i++) {
        scanf("%d %d", &u, &v);
        add_edge(u, v);
        add_edge(v, u);
    }
    dfs(1, 0);
    for (int i = 1; i <= n; i++) {
        point[i] = (Point) {dfn[i], dep[i], size[i] - 1};
    }
    for (int p, k, i = 1; i <= m; i++) {
        scanf("%d %d", &p, &k);
        ans[i] += min(dep[p], k) * (size[p] - 1);
        q[++qcnt] = (Query) {dfn[p], dep[p] + 1, min(dep[p] + k, n), -i};
        q[++qcnt] = (Query) {dfn[p] + size[p] - 1, dep[p] + 1, min(dep[p] + k, n), i};
    }
    sort(point + 1, point + n + 1);
    sort(q + 1, q + qcnt + 1);
    for (int i = 1, now = 1; i <= n; i++) {
        add(point[i].y, point[i].w);
        while (q[now].x <= point[i].x && now <= qcnt) {
            int id = q[now].id;
            if (id < 0) {
                ans[-id] -= query(q[now].y2) - query(q[now].y1 - 1);
            } else {
                ans[id] += query(q[now].y2) - query(q[now].y1 - 1);
            }
            now++;
        }
    }
    for (int i = 1; i <= m; i++) {
        printf("%lld\n", ans[i]);
    }
    return 0;
}

by maruize @ 2022-08-03 17:35:07

您是光第5个点对我是光第5个点错(((((


by maruize @ 2022-08-03 17:42:17

你没开long long?


|