Luogu P2664 树上游戏 dfs+树上统计
题目:
分析:
本来是练习点分治的时候看到了这道题。无意中发现题解中有一种方法可以O(N)解决这道题,就去膜拜了一下。
这个方法是,假如对于某一种颜色,将所有这种颜色的点全部删去,原树会被割成若干棵小树,那么这个颜色对每个点的贡献就是:树的大小n - 所在小树的大小sz。所以我们要求出对于每个点来说,删去所有这个点颜色的点,这个点以下的小树size,这个用一个dfs和一个类似前缀和相减的过程,就可以求出。
接下来统计每个点的答案,就是所有颜色对这个点的贡献:n*颜色数-对于每种颜色这个点所处的小树size,这个用一遍dfs也可以求出来,类似容斥的思想。
代码中有注释:
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=;
struct node{int y,nxt;}e[N*];
ll n,sm,qwq,vis[N],ans[N],c=,h[N];
ll col[N],siz[N],tmp[N],lz[N],sn[N];
void add(int x,int y){
e[++c]=(node){y,h[x]};h[x]=c;
e[++c]=(node){x,h[y]};h[y]=c;
} void dfs(int x,int fa){
siz[x]=;ll cnt=tmp[col[fa]];
for(int i=h[x],y;i;i=e[i].nxt)
if((y=e[i].y)!=fa) dfs(y,x),siz[x]+=siz[y];
tmp[col[x]]++;if(fa){
lz[x]=siz[x]-tmp[col[fa]]+cnt;
tmp[col[fa]]+=lz[x];
} return ;
} void get(int x,int fa){
ll sgn=sn[col[fa]];
qwq+=lz[x]-sn[col[fa]];
sn[col[fa]]=lz[x];
ans[x]=n*sm-qwq+sn[col[x]];
for(int i=h[x],y;i;i=e[i].nxt)
if((y=e[i].y)!=fa) get(y,x);
sn[col[fa]]=sgn;
qwq-=lz[x]-sn[col[fa]];
} int main(){
scanf("%lld",&n);
for(int i=;i<=n;i++){
scanf("%lld",&col[i]);
if(!vis[col[i]])
vis[col[i]]=,sm++;
} for(int i=,x,y;i<n;i++)
scanf("%d%d",&x,&y),add(x,y);
dfs(,);
for(int i=;i<=;i++)
if(vis[i]) qwq+=n-tmp[i],
sn[i]=n-tmp[i];get(,);
for(int i=;i<=n;i++)
printf("%lld\n",ans[i]);return ;
}//lz[x]表示将x的父节点这种颜色的点全部删掉余下的这个
//小树的size
//sn记录的是对于每种颜色,当前深度以上的最近的小树sz
//qwq变量计算的是当前位置对于每种颜色所处的小树sz总和
dfs+树上统计
Luogu P2664 树上游戏 dfs+树上统计的更多相关文章
- Luogu P1278 单词游戏(dfs)
P1278 单词游戏 题意 题目描述 \(Io\)和\(Ao\)在玩一个单词游戏. 他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致. 游戏可以从任何 ...
- 洛谷 P2664 树上游戏 解题报告
P2664 树上游戏 题目描述 \(\text{lrb}\)有一棵树,树的每个节点有个颜色.给一个长度为\(n\)的颜色序列,定义\(s(i,j)\) 为 \(i\) 到 \(j\) 的颜色数量.以及 ...
- P2664 树上游戏
P2664 树上游戏 https://www.luogu.org/problemnew/show/P2664 分析: 点分治. 首先关于答案的统计转化成计算每个颜色的贡献. 1.计算从根出发的路径的答 ...
- 【Luogu2664】树上游戏(点分治)
[Luogu2664]树上游戏(点分治) 题面 洛谷 题解 很好的一道点分治题. 首先直接点分治,考虑过每个分治重心的链的贡献. 我们从分治重心开始找每种颜色,强制令一种颜色只在其到分治重心的链上第一 ...
- LG2664 树上游戏
树上游戏 题目描述 lrb有一棵树,树的每个节点有个颜色.给一个长度为n的颜色序列,定义s(i,j) 为i 到j 的颜色数量.以及 $$sum_i=\sum_{j=1}^ns(i,j)$$ 现在他想让 ...
- Luogu P2680 运输计划(二分+树上差分)
P2680 运输计划 题意 题目背景 公元\(2044\)年,人类进入了宇宙纪元. 题目描述 公元\(2044\)年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道 ...
- BZOJ_4238_电压_树上差分+dfs树
BZOJ_4238_电压_树上差分+dfs树 Description 你知道Just Odd Inventions社吗?这个公司的业务是“只不过是奇妙的发明(Just Odd Inventions)” ...
- 【bzoj3779】重组病毒 LCT+树上倍增+DFS序+树状数组区间修改区间查询
题目描述 给出一棵n个节点的树,每一个节点开始有一个互不相同的颜色,初始根节点为1. 定义一次感染为:将指定的一个节点到根的链上的所有节点染成一种新的颜色,代价为这条链上不同颜色的数目. 现有m次操作 ...
- [luogu]P1070 道路游戏[DP]
[luogu]P1070 道路游戏 题目描述小新正在玩一个简单的电脑游戏.游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针 ...
随机推荐
- Window 10 Alt Tap 切换窗口,设置成Windows 7风格
升级了Windows 10 以后,切换窗口非常的难受.新版的窗口切换的图标变成了窗口预览了,这总让我一瞬间找不到要去的窗口,所以我打算切换成Windows 7 的小图标风格. Windows + R ...
- suse 11.4添加阿里源
感谢SilenMark 作者,让我找到了一个可用的suse 国内源. 大家直接使用root 用户执行以下命令,添加阿里源 zypper addrepo -f http://mirrors.aliyun ...
- MyBais中xxMap.xml中的知识点
添加新的mapper的时候下面两个标红的地方要注意,如果统一约定好命名的话都还好,但是就怕一会这样一会那样的业务代码:总之小心! <!-- spring与mybatis整合配置,扫描所有dao, ...
- BZOJ3224普通平衡树
洛谷题面链接 很早就过了,太久没打了,原本是在noip前用来练emacs的手感的. noip炸了,就滚回来更博客了(安排的计数任务刷不动,学不会容斥,打发时间...) 众所周知,splay是个好算法, ...
- [Usaco2011 Dec]Grass Planting
Description Farmer John has N barren pastures connected by N-1 bidirectional roads, such that there ...
- [JLOI2016]圆的异或并
Description 在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面积并.异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个圆 ...
- Codeforces 1107F(dp)
怎么就没人解释一下为啥用b排序可以保证正确性呢……太菜了,理解了好久. 时间流逝价值会丢失的背包,类似题洛谷1417 本题与洛谷1417不同之处在于流逝是有截止的. 1.这个dp[j]的含义是:最后跑 ...
- MFC中的模态对话框与非模态对话框
模态对话框创建: MyDialog mydlg; mydlg.DoModal() 当前只能运行此模态对话框,且停止主窗口的运行,直到模态对话框退出,才允许主窗口运行. 模态对话框的关闭顺序: OnCl ...
- OS 内存泄漏 导致 整个aix主机block
问题 aix 主机 1.数据库主机使用vmstat 监控,隔几分钟 就是block 爆满. cpu 没有瓶颈,I/O 显示本地磁盘hdisk0和hdisk 1 是爆满. vmstat 同时显示大量pa ...
- python学习之队列
import queue task_queue = queue.Queue() #创建队列