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. 2019-7-17 正则表达式和re模块

    一.re模块与正则表达式之间的关系 正则表达式不是python独有的,它是一门独立的技术 所有的编程语言都可以使用正则 但是如果你想在python中使用,你就必须依赖于re模块 正则的官方定义:正则表 ...

  2. 7. Spark SQL的运行原理

    7.1 Spark SQL运行架构 Spark SQL对SQL语句的处理和关系型数据库类似,即词法/语法解析.绑定.优化.执行.Spark SQL会先将SQL语句解析成一棵树,然后使用规则(Rule) ...

  3. jQuery基础事件处理

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Codeforces Round #581 (Div. 2)

    A:暴力. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm& ...

  5. java之mybatis之使用mybatis实现crud操作

    目录结构: 1.封装 mybatis 的工具类: MybatisUtil.java public class MybatisUtil { private static SqlSessionFactor ...

  6. MyBatis和spring整合简单实现

    spring和MyBatis整合: 导入spring和MyBatis的整合jar包,以及其依赖jar包: 导入MyBatis和spring的整合jar包. spring的核心jar包. 定义Mybat ...

  7. Java自学-数组 增强型for循环

    Java 中如何使用增强for循环 增强型for循环在遍历一个数组的时候会更加快捷 步骤 1 : 增强型for循环 注:增强型for循环只能用来取值,却不能用来修改数组里的值 public class ...

  8. JQuey中ready()的4种写法

    在jQuery中,对于ready()方法,共有4种写法: (1)写法一: $(document).ready(functin(){ //代码部分 }) 分析:这种代码形式是最常见的,其中$(docum ...

  9. 金融finaunce单词finaunce财经

    金融(FINANCE或FINAUNCE)就是对现有资源进行重新整合之后,实现价值和利润的等效流通.(专业的说法是:实行从储蓄到投资的过程,狭义的可以理解为金融是动态的货币经济学.) 金融是人们在不确定 ...

  10. Celery:Next Steps

    参考文档:http://docs.celeryproject.org/en/latest/getting-started/next-steps.html#next-steps