LINK:旗鼓相当的对手

考场上遇到这种简单的树形dp优化题目我真的不一定能写出来..

虽然这道题思路很简单 设f[i][j]表示距i距离为j的点的个数 g[i][j]表示距i距离为j的点权和。

可以发现我们转枚举子树转移的时候可以得到某个点的答案。其实这道题让我们求的是以x为根的所有子树之间的答案。

这两个数组转移以深度转移 所以复杂度为n^2 长链刨分一下即可O(n)。

但是我并不会长链刨分时的指针写法。所以考虑其他做法。

可以发现如果维护这两个数组的转移必然n^2 这个时候我们考虑直接给全局贡献 即每个点x以d[x]为深度的贡献。

这样我们就不需要维护距某个点的深度了 直接查d[x]+k的距离即可。

但是这需要子树内外的差分。暴力差分还是n^2.

考虑dsu on tree 暴力把轻儿子删掉之后统计重儿子 然后重儿子的代价保留。

对于某个点我们再次遍历所有轻儿子一边统计答案一边累计数组。

最后如果这个点也是轻儿子那么再次情况即可。

一个点距根节点只有logn条轻边 所以这样做复杂度nlogn.

const int MAXN=100010;
int n,len,k;ll ans[MAXN],w[MAXN],sum;
int son[MAXN],a[MAXN],d[MAXN],f[MAXN],cnt[MAXN],sz[MAXN];
int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1];
inline void add(int x,int y)
{
ver[++len]=y;nex[len]=lin[x];lin[x]=len;
ver[++len]=x;nex[len]=lin[y];lin[y]=len;
}
inline void dfs(int x,int father)
{
sz[x]=1;f[x]=father;
d[x]=d[father]+1;
go(x)
{
if(tn==father)continue;
dfs(tn,x);
sz[x]+=sz[tn];
if(sz[son[x]]<sz[tn])son[x]=tn;
}
}
inline void update(int x,int fa,int op)
{
int ww=k+2*d[fa]-d[x];
if(ww>0&&op>0&&x!=fa)
{
sum=sum+(ll)cnt[ww]*a[x];
sum=sum+w[ww];
}
go(x)if(tn!=f[x])update(tn,fa,op);
}
inline void add(int x,int fa,int op)
{
cnt[d[x]]+=op;w[d[x]]+=op*a[x];
go(x)if(tn!=f[x])add(tn,fa,op);
}
inline void dp(int x,int op)
{
go(x)if(tn!=f[x]&&tn!=son[x])dp(tn,0);//先处理轻儿子.
if(son[x])dp(son[x],1);//处理重儿子.
go(x)if(tn!=f[x]&&tn!=son[x])update(tn,x,1),add(tn,x,1);
++cnt[d[x]];w[d[x]]+=a[x];ans[x]=sum;sum=0;
if(!op)add(x,x,-1);
}
int main()
{
freopen("1.in","r",stdin);
get(n);get(k);
rep(1,n,i)get(a[i]);
rep(1,n-1,i)add(read(),read());
dfs(1,0);dp(1,1);
rep(1,n,i)printf("%lld ",ans[i]);
return 0;
}

牛客练习赛60 E 旗鼓相当的对手的更多相关文章

  1. 牛客练习赛60 A—F题解(缺E题)

    本蒟蒻这次只过了三题 赛后学习了一下出题人巨佬的标码(码风比我好多了 贴的代码有些是仿出题人)现在将自己的理解写下来与大家分享 A这个题一分析就是每个数字都会与所有数字&一下 (a&a ...

  2. 牛客练习赛60 D 斩杀线计算大师

    LINK:斩杀线计算大师 给出a,b,c三个值 求出 ax+by+cz=k的x,y,z的正整数解 保证一定有解. 考虑两个数的时候 ax+by=k 扩展欧几里得可以解决. 三个数的时候 一个暴力的想法 ...

  3. 牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 逻辑,博弈 B

    牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 https://ac.nowcoder.com/acm/contest/218/B 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 2621 ...

  4. [堆+贪心]牛客练习赛40-B

    传送门:牛客练习赛40 题面: 小A手头有 n 份任务,他可以以任意顺序完成这些任务,只有完成当前的任务后,他才能做下一个任务 第 i 个任务需要花费  x_i 的时间,同时完成第 i 个任务的时间不 ...

  5. 【并查集缩点+tarjan无向图求桥】Where are you @牛客练习赛32 D

    目录 [并查集缩点+tarjan无向图求桥]Where are you @牛客练习赛32 D PROBLEM SOLUTION CODE [并查集缩点+tarjan无向图求桥]Where are yo ...

  6. 牛客练习赛31 D 神器大师泰兹瑞与威穆 STL,模拟 A

    牛客练习赛31 D 神器大师泰兹瑞与威穆 https://ac.nowcoder.com/acm/contest/218/D 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 26214 ...

  7. 最小生成树--牛客练习赛43-C

    牛客练习赛43-C 链接: https://ac.nowcoder.com/acm/contest/548/C 来源:牛客网 题目描述 ​ 立华奏是一个刚刚开始学习 OI 的萌新. 最近,实力强大的 ...

  8. 牛客练习赛28-B(线段树,区间更新)

    牛客练习赛28 - B 传送门 题目 qn姐姐最好了~ ​ qn姐姐给你了一个长度为n的序列还有m次操作让你玩, ​ 1 l r 询问区间[l,r]内的元素和 ​ 2 l r 询问区间[l,r]内的 ...

  9. 牛客练习赛26:D-xor序列(线性基)

    链接:牛客练习赛26:D-xor序列(线性基) 题意:小a有n个数,他提出了一个很有意思的问题:他想知道对于任意的x, y,能否将x与这n个数中的任意多个数异或任意多次后变为y 题解:线性基 #inc ...

随机推荐

  1. 控制流程之while循环, for循环

    条件循环:while,语法如下 while 条件: # 循环体 # 如果条件为真,那么循环体则执行,执行完毕后再次循环,重新判断条件... # 如果条件为假,那么循环体不执行,循环终止死循环 基本使用 ...

  2. vue+element-ui JYAdmin后台管理系统模板-集成方案【项目搭建篇2】

    项目搭建时间:2020-06-29 本章节:讲述基于vue/cli, 项目的基础搭建. 本主题讲述了: 1.跨域配置 2.axios请求封装 3.eslint配置 4.环境dev,test,pro(开 ...

  3. node+express实现简单的增删改查

    var express = require('express'); var bodyParser = require("body-parser"); var cors = requ ...

  4. JVM 学习笔记(五)

    前言: 前面的文件介绍了JVM的内存模型以及各个区域存放了那些内容,本编文章将介绍JVM中的垃圾回收Garbage Collector,和大家一起探讨一下. 如何确定一个对象是垃圾: 这里介绍两种方法 ...

  5. djangorestframework学习1-通过HyperlinkedModelSerializer,ModelViewSet,routers编写第一个接口

    前提首先安装了django,安装方式:pip install django 1. djangorestftamework安装: pip install djangorestframework 2. 创 ...

  6. scala 数据结构(八 ):-map映射操作

    在Scala中可以通过map映射操作来解决: 将集合中的每一个元素通过指定功能(函数)映射(转换)成新的结果集合这里其实就是所谓的将函数作为参数传递给另外一个函数,这是函数式编程的特点 以HashSe ...

  7. nginx: command not found

    nginx 正常启动,可以访问服务器地址:welcome to nginx 使用nginx -t 等命令时 报错:nginx: command not found 这是环境变量未配置 配置环境变量 v ...

  8. OSCP Learning Notes - Exploit(8)

    Tools: 3. hydra Hydra v8.9.1 (c) 2019 by van Hauser/THC - Please do not use in military or secret se ...

  9. python 复制以及更改列表操作

    题目:设置一个老用户列表和一个新用户列表,检查老用户列表中是否与新注册的用户名字有重复(不区分大小写),老用户列表不能被破坏 usernames = ['admin','Tom','john','ja ...

  10. GEDIT外部工具

    首先通过编辑-首选项-插件-外部命令来打开外部命令,然后在工具-Manage External Tools来添加新工具,工具代码使用bash语言. 代码使用方式:+添加新插件,在编辑框中粘贴代码,快捷 ...