WorldBest丶牛顿 @ 2019-09-28 15:31:27
用的树剖lca + 树上差分,算法是看了 一扶苏一
dalao的题解写的,但是只有80分(这么说窝还不如写暴力??)
求大佬帮我看看哪里可以优化的
#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
注释我还可以加,,或者对我码风有意见建议我也会听,但是不要觉得我在
by MC方块人 @ 2019-09-28 15:47:00
@WorldBest丶牛顿 fake,你个做黑题的蒟蒻?
by WorldBest丶牛顿 @ 2019-09-28 15:49:09
@MC方块人 你看我认证还是绿色的就知道我是蒟蒻了
by MC方块人 @ 2019-09-28 15:54:45
@WorldBest丶牛顿 那我们没勾的是什么?!
by WorldBest丶牛顿 @ 2019-10-02 19:00:23
好,我sb了,树剖dfs被我打成暴力lca了