真蒟蒻的求助qwq

P1600 [NOIP2016 提高组] 天天爱跑步

WorldBest丶牛顿 @ 2019-09-28 15:31:27

用的树剖lca + 树上差分,算法是看了 一扶苏一 dalao的题解写的,但是只有80分(这么说窝还不如写暴力??) 求大佬帮我看看哪里可以优化的qwq

#include <bits/stdc++.h>
using namespace std;

char getch()
{
    static char buf[1 << 14], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 14, stdin), p1 == p2) ? EOF : *p1++;
}

void read(int &x)
{
    x = 0;
    char c = getch();
    while(c < '0' || c > '9') c = getch();
    while(c >= '0' && c <= '9')
    {
        x = x * 10 + (c - '0');
        c = getch();
    }
}

const int MAXN = 500003;
int n, m, cnt;
int head[MAXN], w[MAXN], ans[MAXN], lft[MAXN], rgt[MAXN];//lft是从下往上走的,rgt是从上往下走的
int fa[MAXN], dep[MAXN], top[MAXN], son[MAXN], tot[MAXN];//树剖数组
struct node
{
    int v, next;
}e[MAXN];
struct human
{
    int s, t, lca;
}f[MAXN];
struct bucket
{
    int dir, dep, num;
    //走的方向(1是向上,2是向下),dep是要修改的点的深度, num是 +1/-1
    bucket(int x, int y, int z) {dir = x; dep = y; num = z;}
};
vector<bucket> buc[MAXN];

void add(int u, int v)
{
    e[++cnt].v = v;
    e[cnt].next = head[u];
    head[u] = cnt;
}

void dfs1(int u)
{
    tot[u]++;
    for(int i = head[u]; i; i = e[i].next)
    {
        int v = e[i].v;
        if(v == fa[u]) continue;
        fa[v] = u; dep[v] = dep[u] + 1;
        dfs1(v); tot[u] += tot[v];
        if(tot[son[u]] < tot[v]) son[u] = v;
    }
}

void dfs2(int u, int topf)
{
    top[u] = topf;
    if(!son[u]) return;
    dfs2(son[u], topf);
    for(int i = head[u]; i; i = e[i].next)
    {
        int v = e[i].v;
        if(!top[v]) dfs2(v, v);
    }
}

void dfs3(int u)
{
    int tmp = lft[dep[u] + w[u]] + rgt[dep[u] - w[u] + MAXN];
    for(int i = head[u]; i; i = e[i].next)
    {
        int v = e[i].v;
        if(v != fa[u]) dfs3(v);
    }
    for(int i = 0; i < buc[u].size(); ++i)
    {
        if(buc[u][i].dir == 1) lft[buc[u][i].dep] += buc[u][i].num;
        else rgt[buc[u][i].dep] += buc[u][i].num;
    }
    ans[u] += lft[dep[u] + w[u]] + rgt[dep[u] - w[u] + MAXN] - tmp;
}

int lca(int x, int y)
{
    while(top[x] != top[y])
    {
        if(dep[x] < dep[y]) swap(x, y);
        x = fa[x];
    }
    return dep[x] < dep[y] ? x : y;
}

int main()
{
    read(n); read(m);
    for(int i = 1, u, v; i < n; ++i)
    {
        read(u); read(v);
        add(u, v); add(v, u);
    }
    for(int i = 1; i <= n; ++i) read(w[i]);

    dfs1(1); dfs2(1, 1);//树剖
    for(int i = 1; i <= m; ++i)
    {
        read(f[i].s); read(f[i].t);
        f[i].lca = lca(f[i].s, f[i].t);

        buc[f[i].s].push_back(bucket(1, dep[f[i].s], 1));
        buc[f[i].lca].push_back(bucket(1, dep[f[i].s], -1));
        //lft : dep[tmp] + w[tmp] = dep[s]
        buc[f[i].t].push_back(bucket(2, 2 * dep[f[i].lca] - dep[f[i].s] + MAXN, 1));
        buc[fa[f[i].lca]].push_back(bucket(2, 2 * dep[f[i].lca] - dep[f[i].s] + MAXN, -1));
        //rgt : dep[tmp] - w[tmp] = dep[t] - ((dep[s] - dep[lca]) + (dep[t] - dep[lca]))
        //                        = 2 * dep[lca] - dep[s]
    }

    dfs3(1);
    for(int i = 1; i <= n; ++i) printf("%d ", ans[i]);
    return 0;
}

by muyang_233 @ 2019-09-28 15:31:57

Orz 您这个蒟蒻都会我不会的东西 那我岂不是要菜死了


by Provicy @ 2019-09-28 15:32:27

我没掉了


by WorldBest丶牛顿 @ 2019-09-28 15:37:16

注释我还可以加,,或者对我码风有意见建议我也会听,但是不要觉得我在 fAKeqwq


by MC方块人 @ 2019-09-28 15:47:00

@WorldBest丶牛顿 fake,你个做黑题的蒟蒻?


by WorldBest丶牛顿 @ 2019-09-28 15:49:09

@MC方块人 你看我认证还是绿色的就知道我是蒟蒻了qwq


by MC方块人 @ 2019-09-28 15:54:45

@WorldBest丶牛顿 那我们没勾的是什么?!


by WorldBest丶牛顿 @ 2019-10-02 19:00:23

好,我sb了,树剖dfs被我打成暴力lca了


|