https://www.luogu.org/problemnew/show/P2664

考虑对于每种颜色包含的点和这些点的子节点建出虚树,发现只要将一个联通块中的东西 Dp + 差分一下就行了

当然要考虑哪些东西要被加进去

如果把不是一个颜色的联通块放在一起加,里面就要算上 n - 联通块大小的贡献(画个图就行了

然后输出的时候每个点的贡献要 + n (因为自己对任何一个点的连边肯定包含自己这种颜色

博主差分的时候写挂了导致要 #define int long long,而且常数巨大

#include <bits/stdc++.h>
#define int long long
using namespace std; const int N = 1e5 + 5, LG = 17; vector <int> col[N], G[N], mdf[N], G2[N];
int pre[N][LG + 1], dep[N], sta[N], a[N], s[N], id[N], siz[N], book[N], f[N], h[N * 2];
int n, len, dfn, maxn, k; void init(int u, int fa) {
pre[u][0] = fa; dep[u] = dep[fa] + 1; id[u] = ++dfn; siz[u] = 1;
for(int i = 1; i <= LG; i++) pre[u][i] = pre[pre[u][i - 1]][i - 1];
for(vector <int> :: iterator it = G[u].begin(); it != G[u].end(); it++)
if(*it != fa) init(*it, u), siz[u] += siz[*it];
} int jump(int x, int k) {
for(int i = LG; i >= 0; i--)
if(k & (1 << i))
x = pre[x][i];
return x;
} int LCA(int x, int y) {
if(dep[x] > dep[y]) swap(x, y);
y = jump(y, dep[y] - dep[x]);
if(x == y) return x;
for(int i = LG; i >= 0; i--)
if(pre[x][i] != pre[y][i])
x = pre[x][i], y = pre[y][i];
return pre[x][0];
} bool cmp(int x, int y) {return id[x] < id[y];} void dfs1(int u, int top) {
if(book[u] == 0 && G[u].size() == 0) {
f[u] = siz[u]; return;
}
if(book[u] == 1) {
f[u] = 0;
for(vector <int> :: iterator it = G[u].begin(); it != G[u].end(); it++) {
int len = (dep[*it] - dep[u] - 1);
int son = jump(*it, len);
if(book[*it] == 1) {
dfs1(*it, top);
int sz = siz[son] - siz[*it];
s[son] += (n - sz); s[*it] -= (n - sz);
} else {
mdf[son].clear(); dfs1(*it, son);
int sz = siz[son] - siz[*it];
int allsz = sz + f[*it];
s[son] += (n - allsz);
for(vector <int> :: iterator itt = mdf[son].begin(); itt != mdf[son].end(); itt++) s[*itt] -= (n - allsz);
}
}
} else {
f[u] = siz[u];
for(vector <int> :: iterator it = G[u].begin(); it != G[u].end(); it++) {
int len = (dep[*it] - dep[u] - 1);
int son = jump(*it, len);
dfs1(*it, top);
if(book[*it] == 1) {
mdf[top].push_back(*it);
f[u] -= siz[*it];
} else {
f[u] -= (siz[*it] - f[*it]);
}
}
}
} void dfs2(int u, int fa) {
s[u] += s[fa];
for(vector <int> :: iterator it = G2[u].begin(); it != G2[u].end(); it++) {
if(*it != fa) dfs2(*it, u);
}
} signed main() {
cin >> n;
for(int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
col[a[i]].push_back(i);
maxn = max(maxn, a[i]);
}
for(int i = 1; i < n; i++) {
int a, b;
scanf("%lld %lld", &a, &b);
G[a].push_back(b);
G[b].push_back(a);
G2[a].push_back(b);
G2[b].push_back(a);
}
init(1, 0);
G[n + 1].push_back(1); book[n + 1] = 1;
for(int i = 1; i <= maxn; i++) {
k = col[i].size();
for(int j = 0; j < k; j++) h[j + 1] = col[i][j], book[col[i][j]] = 1;
int tmp = k; bool have = 0;
for(int j = 1; j <= tmp; j++) {
int u = h[j];
if(u == 1) have = 1;
for(vector <int> :: iterator it = G2[u].begin(); it != G2[u].end(); it++) {
if(*it != pre[u][0]) h[++k] = *it;
}
}
if(!have) {
for(vector <int> :: iterator it = G2[1].begin(); it != G2[1].end(); it++) {
h[++k] = *it;
}
}
sort(h + 1, h + k + 1, cmp);
k = unique(h + 1, h + k + 1) - h - 1;
sort(h + 1, h + k + 1, cmp);
sta[len = 1] = 1; G[1].clear();
for(int j = 1; j <= k; j++) {
if(h[j] == 1) continue;
int lca = LCA(h[j], sta[len]);
if(lca != sta[len]) {
while(id[lca] < id[sta[len - 1]]) {
G[sta[len - 1]].push_back(sta[len]);
len--;
}
if(id[lca] > id[sta[len - 1]]) {
G[lca].clear();
G[lca].push_back(sta[len]);
sta[len] = lca;
} else G[lca].push_back(sta[len]), len--;
}
G[h[j]].clear(); sta[++len] = h[j];
}
for(int j = 1; j < len; j++) G[sta[j]].push_back(sta[j + 1]);
dfs1(n + 1, 0); for(int j = 0; j < tmp; j++) book[col[i][j]] = 0;
}
dfs2(1, 0);
for(int i = 1; i <= n; i++) printf("%lld\n", s[i] + n);
return 0;
}

luoguP2664 树上游戏的更多相关文章

  1. luoguP2664树上游戏(点分治)

    题目链接:https://www.luogu.org/problem/P2664 题意:给定一颗带点权的树,结点数n<=1e5,点权<=1e5,用s(i,j)表示从i到j的路径上不同点权数 ...

  2. 【点分治】luoguP2664 树上游戏

    应该是一道中等难度的点分?麻烦在一些细节. 题目描述 lrb有一棵树,树的每个节点有个颜色.给一个长度为n的颜色序列,定义s(i,j) 为i 到j 的颜色数量.以及 现在他想让你求出所有的sum[i] ...

  3. 【Luogu2664】树上游戏(点分治)

    [Luogu2664]树上游戏(点分治) 题面 洛谷 题解 很好的一道点分治题. 首先直接点分治,考虑过每个分治重心的链的贡献. 我们从分治重心开始找每种颜色,强制令一种颜色只在其到分治重心的链上第一 ...

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

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

  5. P2664 树上游戏

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

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

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

  7. LG2664 树上游戏

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

  8. 【Luogu P2664】树上游戏

    Problem Description \(lrb\) 有一棵树,树的每个节点有个颜色.给一个长度为 \(n\) 的颜色序列,定义 \(s(i,j)\) 为 \(i\) 到 \(j\) 的颜色数量.以 ...

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

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

随机推荐

  1. Python re模块与正则表达式的运用

    re模块 永远不要起一个py文件的名字,这个名字和你已知的模块同名 查找 findall():     匹配所有   每一项都是列表中的一个元素 语法 :   findall(正则判断条件,要判断字符 ...

  2. js 判断浏览器类型大全

    /**** * 目前识别范围 * Microsoft Internet Explorer IE浏览器 * --> TheWorld 世界之窗 * --> TT浏览器 * --> 36 ...

  3. Activex感知网页刷新关闭事件

    原因 大多数ActiveX控件框架,例如MFC和ATL,在本地激活ActiveX控件时创建控件.基于性能上的考虑,直到控件第一次可见的时候,IE才本地激活ActiveX控件.这样包含ActiveX控件 ...

  4. PHP数据结构之三 线性表中的单链表的PHP实现

    线性表的链式存储:用一组任意的存储单元存储线性表中的数据元素.用这种方法存储的线性表简称线性链表. 链式存储线性表的特点:存储链表中结点的一组任意的存储单元可以是连续的,也可以是不连续的,甚至是零散分 ...

  5. 【NOIP2008】传纸条

    [描述] Description 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就 ...

  6. wangEditor富文本编辑器

    设置好了是这样的, 有一个ID问content的编辑框,方便获取,这里的富文本编辑器的版本是2.2 官方文档说3就不支持textarea了 导入一下css 记得css文件夹下应该又3个文件,虽然没有直 ...

  7. HtmlHelper扩展

    扩展 HtmlHelper类 public static class MyHtmlHelper { //扩展方法 //静态类,静态方法,this关键字 //调用方法<%=Html.MyLabel ...

  8. Python学习笔记_一个Tkinter示例,使用FileDialog

    为了使用Python进行数据分析,编写一个图形界面,选择一个Excel文件(或CSV),然后进行后续处理. 一.本示例涵盖如下知识点: 1.FileDialog的使用 2.退出程序 3.消息提示框的示 ...

  9. jQuery--修改表单数据并提交

    目的: ​点击'编辑',弹出对话框,修改数据. 主要知识点: prevAll(),获取同级别本元素前面的所有元素. 代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

  10. logistic growth model . 求解方法 (高斯牛顿法)

    https://www.stat.tamu.edu/~jnewton/604/chap4.pdf http://www.metla.fi/silvafennica/full/sf33/sf334327 ...