CF1923E Count Paths

点分治模板题。

假设当前处理的树根为 \(x\),我们考虑如何统计经过点 \(x\) 的合法路径。

\(1\):存在一个与 \(x\) 颜色相同的点,且这个点到 \(x\) 的路径上没有与之颜色相同的点,那么这个点和 \(x\) 就构成了一条合法路径。

\(2\):存在一个与 \(x\) 颜色不相同的点,且这个点到 \(x\) 的路径上没有与之颜色相同的点。那么这个点与 \(x\) 的其他子树中与之颜色相同的点构成一条合法路径。

情况 \(2\) 可以通过记录一个颜色数组,将访问过的到 \(x\) 的路径上没有与之颜色相同的点的节点的颜色进行统计。两棵不同的子树之间的路径匹配时,直接使用颜色数组即可。

接下来就是点分治模板了。每次取重心,统计贡献,删除,递归点分治子树。即可统计所有合法路径。

实现得比较差,常数较大。

#include <bits/stdc++.h>
using namespace std;
struct edge
{
long long v,nxt;
}e[600000];
long long t,n,a[300000],s[300000],h[300000],del[300000],he=0,cnt=0,ans=1e10,tol=0;
long long pre[300000],x[300000],sum[300000],g[300000];
void init()
{
for(int i=1;i<=n;i++)del[i]=0,h[i]=0;
tol=0,cnt=0;
} void add_edge(long long u,long long v)
{
e[++cnt].nxt=h[u];
e[cnt].v=v;
h[u]=cnt;
} long long dfs1(long long now,long long fa,long long cnt)
{
long long maxn=0;
s[now]=1;
if(del[now])return 0;
for(long long i=h[now];i;i=e[i].nxt)
if(e[i].v!=fa)
{
long long z=dfs1(e[i].v,now,cnt);
s[now]+=z,maxn=max(maxn,z);
}
if(max(maxn,cnt-s[now])<ans)ans=min(ans,max(maxn,cnt-s[now])),he=now;
return s[now];
} void dfs2(long long now,long long fa)
{
if(del[now])return;
s[now]=1,pre[now]=x[a[now]],x[a[now]]=now;
if(pre[now]==0)
{
if(a[now]==a[he])tol++;
else
{
tol+=sum[a[now]];
g[a[now]]++;
}
}
for(long long i=h[now];i;i=e[i].nxt)
if(e[i].v!=fa)
{
dfs2(e[i].v,now);
if(del[e[i].v]==0)s[now]+=s[e[i].v];
}
x[a[now]]=pre[now];
} void update(long long now,long long fa)
{
if(del[now])return;
sum[a[now]]+=g[a[now]],g[a[now]]=0;
for(long long i=h[now];i;i=e[i].nxt)
if(e[i].v!=fa)update(e[i].v,now);
} void clear(long long now,long long fa)
{
if(del[now])return;
pre[now]=0,x[a[now]]=0,sum[a[now]]=0;
for(long long i=h[now];i;i=e[i].nxt)
if(e[i].v!=fa)clear(e[i].v,now);
} void dfz(long long now,long long siz)
{
if(del[now])return;
ans=1e10;
dfs1(now,0,siz);
for(long long i=h[he];i;i=e[i].nxt)
{
dfs2(e[i].v,he);
update(e[i].v,he);
}
for(long long i=h[he];i;i=e[i].nxt)clear(e[i].v,he);
del[he]=1;
for(long long i=h[he];i;i=e[i].nxt)dfz(e[i].v,s[e[i].v]);
} int main()
{
scanf("%lld",&t);
while(t--)
{
scanf("%lld",&n);
init();
for(long long i=1;i<=n;i++)scanf("%lld",&a[i]);
for(long long i=1;i<=n-1;i++)
{
long long u=0,v=0;
scanf("%lld%lld",&u,&v);
add_edge(u,v),add_edge(v,u);
}
dfz(1,n);
printf("%lld\n",tol);
}
return 0;
}

CF1923E Count Paths 题解的更多相关文章

  1. [CF1188B]Count Pairs 题解

    前言 这道题目是道好题. 第一次div-2进前100,我太弱了. 题解 公式推导 我们观察这个式子. \[(a_i+a_j)(a_i^2+a_j^2)\equiv k \mod p\] 感觉少了点什么 ...

  2. CF293B Distinct Paths题解

    CF293B Distinct Paths 题意 给定一个\(n\times m\)的矩形色板,有kk种不同的颜料,有些格子已经填上了某种颜色,现在需要将其他格子也填上颜色,使得从左上角到右下角的任意 ...

  3. "Shortest" pair of paths[题解]

    "Shortest" pair of paths 题目大意 给出 \(n\) 个点,\(m\) 条边,除第一个点和最后一个点外,其他所有的点都只能被经过一次,要求找到两条从第一个点 ...

  4. POJ3068:"Shortest" pair of paths——题解

    http://poj.org/problem?id=3068 题目大意: 从0-n-1找到两条边和点都不相同(除了0和n-1外)的最小费用路径. ——————————————————————————— ...

  5. POJ3177:Redundant Paths——题解

    http://poj.org/problem?id=3177 明显要求桥的一道题. (因为有桥就说明只能从那一条路走,换句话说就是只有一种方法) 求完桥后按照结论(加几条边成双连通图的结论,不会请ba ...

  6. E. Number of Simple Paths 题解(思维)

    题目链接 题目大意 给你n个点(\(\sum n<=2e5\)),n条边,求有多少条路径 题目思路 要明白任意两点的路径只能是1条或者2条 先topo找环(双向边也是可以找的) 然后把环上的每个 ...

  7. [Leetcode Week12]Unique Paths

    Unique Paths 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/unique-paths/description/ Description A ...

  8. CF981H K Paths

    CF981H K Paths 题解 一道不错的分治ntt题目 题目稍微转化一下,就是所有k条链的存在交,并且交的部分都被覆盖k次 所以一定是两个点,之间路径选择k次,然后端点两开花 f[x]表示x子树 ...

  9. Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)部分(A~E)题解

    (A) Even Subset Sum Problem 题解:因为n非常非常小,直接暴力枚举所有区间即可. #include<bits/stdc++.h> using namespace ...

  10. CF14D题解

    CF14D Two Paths题解 题目链接 传送门 题意简述 给定一棵树,找出两条不经过相同点的最长路径,使得他们的长度乘积最大. 题目分析 首先,如果在一棵树上,两条路径没有共同的点,那么这两条路 ...

随机推荐

  1. Web前端入门第 32 问:CSS background 元素渐变背景用法全解

    渐变背景在 CSS 里面就是一个颜色到另一个颜色渐渐变化的样子. 本文示例中,盒子基础样式: .box { margin: 20px; padding: 20px; border: 10px dash ...

  2. Win10/win11系统如何禁用笔记本自带键盘、笔记本键盘禁用后无法恢复解决办法【靠谱】

    原文:[靠谱]Win10/win11系统如何禁用笔记本自带键盘.禁用后无法恢复解决办法 - 搜栈网 (seekstack.cn)

  3. LLM Agent的构建:OpenAI官方指南解读

    本文是对 OpenAI 近期发布的<A Practical Guide to Building Agents>的读后感与总结 Agent火爆的背景 大型语言模型(LLM)处理复杂.多步骤任 ...

  4. 如何将EndNote 和 Word (office)连接起来

    1,首先在电脑上打开word2019,点击左上角的"文件"菜单. 2,然后在打开的文件菜单中点击"选项"的快捷链接. 3,接下来在打开的Word选项窗口中点击左 ...

  5. wso2~介绍

    1. Wso2-apim的介绍 WSO2 API Manager 是一个开源的 API 管理解决方案,旨在帮助组织设计.发布.管理和分析 API.它提供了全面的功能,支持企业在现代应用程序开发中实现更 ...

  6. Tomcat无法启动报错:'Starting Tomcat v9.5 Server at localhost' has encountered a problem

    错误提示 控制台提示 严重: A child container failed during start java.util.concurrent.ExecutionException: org.ap ...

  7. 代码随想录第二十五天 | Leecode 491. 非递减子序列、46. 全排列、47. 全排列 II

    Leecode 491. 非递减子序列 题目描述 给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 .你可以按 任意顺序 返回答案. 数组中可能含有重 ...

  8. git-fame实战操作

    参考网址:https://pydigger.com/pypi/git-fame,https://github.com/casperdcl/git-fame Git-fame 简介: Pretty-pr ...

  9. HarmonyOS NEXT开发教程:加速web页面访问

    在日常app开发中,访问web页面是很常见的功能,在鸿蒙系统中有多种方案来加速web页面的访问,提升用户体验. 首先,可以在Web组件的onAppear方法中对要加载的页面进行预链接,比如: Web( ...

  10. 树-BST基本实现

    之前的数组, 栈, 链表, 队列等都是顺序数据结构, 这里来介绍一个非顺序数据结构, 树. 树在处理有层级相关的数据时非常有用, 还有在存储数据如数据库查询实现等场景也是高频使用. 作为一种分层数据的 ...