code:

#include <bits/stdc++.h>   

#define N 200009   

#define ll long long 

#define setIO(s) freopen(s".in","r",stdin)   

using namespace std; 

ll Sum[N];

int n,edges,root,sn;     

int val[N],hd[N],to[N<<1],nex[N<<1],size[N],mx[N],vis[N],A[N];   

inline void add(int u,int v)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
} void getroot(int u,int ff)
{
size[u]=1,mx[u]=0; for(int i=hd[u];i;i=nex[i])
{
int v=to[i]; if(v==ff||vis[v]) continue; getroot(v,u); size[u]+=size[v]; mx[u]=max(mx[u],size[v]);
} mx[u]=max(mx[u],sn-size[u]); if(mx[u]<mx[root]) root=u; } int ou; ll tmp,tot,bu[N]; map<int,ll>cn[N]; map<int,ll>::iterator it; int dep[N],cnt[N],siz[N]; void getnode(int top,int u,int ff,int cur)
{ if(!cnt[val[u]]) ++cur; ++cnt[val[u]]; Sum[top]+=(ll)cur; siz[u]=1; for(int i=hd[u];i;i=nex[i])
{
int v=to[i]; if(v==ff||vis[v]) continue; getnode(top,v,u,cur); siz[u]+=siz[v];
} --cnt[val[u]];
}
void get_col(int top,int u,int ff)
{
if(!cnt[val[u]]) cn[top][val[u]]+=(ll)siz[u]; ++cnt[val[u]]; for(int i=hd[u];i;i=nex[i])
{ int v=to[i]; if(v==ff||vis[v]) continue; get_col(top,v,u); }
--cnt[val[u]];
}
void calc_v(int u,int ff)
{
ll tt=bu[val[u]]; tmp=tmp-bu[val[u]]+ou; bu[val[u]]=ou; Sum[u]+=tmp; for(int i=hd[u];i;i=nex[i])
{
int v=to[i]; if(vis[v]||v==ff) continue; calc_v(v,u);
} tmp=tmp-bu[val[u]]+tt; bu[val[u]]=tt;
}
void clr(int u,int ff)
{
cn[u].clear();
bu[val[u]]=0;
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(v==ff||vis[v]) continue;
clr(v,u);
}
}
void calc(int u)
{
tot=0; getnode(u,u,0,0); for(int i=hd[u];i;i=nex[i])
{
int v=to[i]; if(vis[v]) continue; // memset(cnt,0,sizeof(cnt)); get_col(v,v,u); for(it=cn[v].begin();it!=cn[v].end();it++)
{
tot+=it->second; bu[it->first]+=it->second;
}
} for(int i=hd[u];i;i=nex[i])
{
int v=to[i]; if(vis[v]) continue; tmp=tot; ou=siz[u]-siz[v]; for(it=cn[v].begin();it!=cn[v].end();it++)
{
bu[it->first]-=it->second; tmp-=it->second;
} ll tt=bu[val[u]]; tmp=tmp-bu[val[u]]+ou; bu[val[u]]=ou; calc_v(v,u); bu[val[u]]=tt; for(it=cn[v].begin();it!=cn[v].end();it++) bu[it->first]+=it->second; } clr(u,0);
}
void dfs(int u)
{
calc(u); vis[u]=1; for(int i=hd[u];i;i=nex[i])
{
int v=to[i]; if(vis[v]) continue; root=0,sn=size[v],getroot(v,u),dfs(root);
}
}
int main()
{
// setIO("input"); int i,j; scanf("%d",&n); for(i=1;i<=n;++i) scanf("%d",&val[i]), A[i]=val[i]; sort(A+1,A+1+n); for(i=1;i<=n;++i) val[i]=lower_bound(A+1,A+1+n,val[i])-A; for(i=1;i<n;++i)
{
int u,v; scanf("%d%d",&u,&v),add(u,v),add(v,u);
} sn=mx[0]=n,root=0,getroot(1,0),dfs(root); for(i=1;i<=n;++i) printf("%lld\n",Sum[i]); return 0;
}

  

【洛谷P2664】 树上游戏 点分治的更多相关文章

  1. 洛谷P2664 树上游戏(点分治)

    题意 题目链接 Sol 神仙题..Orz yyb 考虑点分治,那么每次我们只需要统计以当前点为\(LCA\)的点对之间的贡献以及\(LCA\)到所有点的贡献. 一个很神仙的思路是,对于任意两个点对的路 ...

  2. 洛谷P2664 树上游戏——点分治

    原题链接 被点分治虐的心态爆炸了 题解 发现直接统计路径上的颜色数量很难,考虑转化一下统计方式.对于某一种颜色\(c\),它对一个点的贡献为从这个点出发且包含这种颜色的路径条数. 于是我们先点分一下, ...

  3. 洛谷 P2664 树上游戏 解题报告

    P2664 树上游戏 题目描述 \(\text{lrb}\)有一棵树,树的每个节点有个颜色.给一个长度为\(n\)的颜色序列,定义\(s(i,j)\) 为 \(i\) 到 \(j\) 的颜色数量.以及 ...

  4. 洛谷P2664 树上游戏(点分治)

    传送门 题解 因为一个sb错误调了一个晚上……鬼晓得我为什么$solve(rt)$会写成$solve(v)$啊!!!一个$O(logn)$被我硬生生写成$O(n)$了竟然还能过$5$个点……话说还一直 ...

  5. 洛谷P2664 树上游戏 【点分治 + 差分】

    题目 lrb有一棵树,树的每个节点有个颜色.给一个长度为n的颜色序列,定义s(i,j) 为i 到j 的颜色数量.以及 现在他想让你求出所有的sum[i] 输入格式 第一行为一个整数n,表示树节点的数量 ...

  6. ●洛谷P2664 树上游戏

    题链: https://www.luogu.org/problemnew/show/P2664题解: 扫描线,线段树维护区间覆盖 https://www.luogu.org/blog/ZJ75211/ ...

  7. 【刷题】洛谷 P2664 树上游戏

    题目描述 lrb有一棵树,树的每个节点有个颜色.给一个长度为n的颜色序列,定义s(i,j) 为i 到j 的颜色数量.以及 \[sum_i=\sum_{j=1}^ns(i,j)\] 现在他想让你求出所有 ...

  8. 洛谷P2664 树上游戏

    https://www.luogu.org/problemnew/show/P2664 #include<cstdio> #include<algorithm> #includ ...

  9. P2664 树上游戏

    P2664 树上游戏 https://www.luogu.org/problemnew/show/P2664 分析: 点分治. 首先关于答案的统计转化成计算每个颜色的贡献. 1.计算从根出发的路径的答 ...

  10. Luogu P2664 树上游戏 dfs+树上统计

    题目: P2664 树上游戏 分析: 本来是练习点分治的时候看到了这道题.无意中发现题解中有一种方法可以O(N)解决这道题,就去膜拜了一下. 这个方法是,假如对于某一种颜色,将所有这种颜色的点全部删去 ...

随机推荐

  1. Java 阿拉伯数字转换为中文大写数字

    Java 阿拉伯数字转换为中文大写数字 /** * <html> * <body> * <P> Copyright 1994 JsonInternational&l ...

  2. C#获取文件夹下的所有文件的方法

    目录 #基础知识 #只获取目录下一级的文件夹与文件 # 递归地输出当前运行程序所在的磁盘下的所有文件名和子目录名 正文   #基础知识 1.获得当前运行程序的路径 1 string rootPath ...

  3. ABP(ASP.NET Boilerplate Project)学习总结

    ABP(ASP.NET Boilerplate Project),现下比较流行的一种web框架,因为公司新项目准备使用这种框架,所以写下这篇文章记录下自己一步一步搭建的过程,就当做是对学习的一个总结与 ...

  4. IntelliJ IDEA web项目进行数据库连接时出现java.lang.ClassNotFoundException: com.mysql.jdbc.Driver错误解决办法

    首先看报错信息: 意思是找不到类:  com.mysql.jdbc.Driver.也就是说tomcat找不到MySQL数据库连接要用的jar包! 出现这种错误的原因是: 项目中没有导入这个jar包, ...

  5. Flutter Platform Channels

    Flutter Platform Channels(一) https://www.jianshu.com/p/33ac774f99b1 https://www.jianshu.com/p/c1e206 ...

  6. windows nvlddmkm、DRIVER_POWER_STATE_FAILURE 蓝屏问题的解决资料

    背景与现象描述 博主在最近购买了 机械革命 Z2-R (MECHREVO Z2-R Series GK5CP02) 笔记本电脑后,几乎每天均有不下3次的蓝屏,而且机器热时,更甚,达到每天10次以上,简 ...

  7. 英语foteball足球foteball单词

    现代足球起源地是在英格兰.传说在11世纪,英格兰与丹麦之间有过一场战争,战争结束后,英格兰人在清理战争废墟时发现一个丹麦入侵者的头骨,出于愤恨,他们便用脚去踢这个头骨,一群小孩见了便也来踢,不过他们发 ...

  8. CCProxy代理

    只要局域网内有一台机器能够上网,其他机器就可以通过这台机器上安装的CCProxy来代理共享上网,最大程度的减少了硬件费用和上网费用.只需要在服务器上CCProxy代理服务器软件里进行帐号设置,就可以方 ...

  9. 修改Nodejs内置的npm默认配置路径方法

    Nodejs 内置的npm默认会把模块安装在c盘的用户AppData目录下(吐槽一下:不明白为啥现在的软件都喜欢把资源装在这里) C盘这么小,肯定是不行的,下面一步步修改到D盘 1.打开cmd命令行, ...

  10. mysql replace into 实现存在则更新,不存在则插入

    测试用的mysql数据库: 新建测试表: CREATE TABLE `test` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `text` varchar(2 ...