Problem Statement

You are given an undirected tree with $N$ vertices.

Let us call the vertices Vertex $1$, Vertex $2$, $\ldots$, Vertex $N$. For each $1\leq i\leq N-1$, the $i$-th edge connects Vertex $U_i$ and Vertex $V_i$.

Additionally, each vertex is assigned a positive integer: Vertex $i$ is assigned $A_i$.

The cost between two distinct vertices $s$ and $t$, $C(s,t)$, is defined as follows.

Let $p_1(=s)$, $p_2$, $\ldots$, $p_k(=t)$ be the vertices of the simple path connecting Vertex $s$ and Vertex $t$, where $k$ is the number of vertices in the path (including the endpoints).

Then, let $C(s,t)=k\times \gcd (A_{p_1},A_{p_2},\ldots,A_{p_k})$,

where $\gcd (X_1,X_2,\ldots, X_k)$ denotes the greatest common divisor of $X_1,X_2,\ldots, X_k$.

Find $\displaystyle\sum_{i=1}^{N-1}\sum_{j=i+1}^N C(i,j)$, modulo $998244353$.

Constraints

  • $2 \leq N \leq 10^5$
  • $1 \leq A_i\leq 10^5$
  • $1\leq U_i<V_i\leq N$
  • All values in input are integers.
  • The given graph is a tree.

Input

Input is given from Standard Input in the following format:

$N$
$A_1$ $A_2$ $\cdots$ $A_N$
$U_1$ $V_1$
$U_2$ $V_2$
$\vdots$
$U_{N-1}$ $V_{N-1}$

Output

Print $\displaystyle\sum_{i=1}^{N-1}\sum_{j=i+1}^N C(i,j)$, modulo $998244353$.


Sample Input 1

4
24 30 28 7
1 2
1 3
3 4

Sample Output 1

47

There are edges directly connecting Vertex $1$ and $2$, Vertex $1$ and $3$, and Vertex $3$ and $4$.
Thus, the costs are computed as follows.

  • $C(1,2)=2\times \gcd(24,30)=12$
  • $C(1,3)=2\times \gcd(24,28)=8$
  • $C(1,4)=3\times \gcd(24,28,7)=3$
  • $C(2,3)=3\times \gcd(30,24,28)=6$
  • $C(2,4)=4\times \gcd(30,24,28,7)=4$
  • $C(3,4)=2\times \gcd(28,7)=14$

Thus, the sought value is $\displaystyle\sum_{i=1}^{3}\sum_{j=i+1}^4 C(i,j)=(12+8+3)+(6+4)+14=47$ modulo $998244353$, which is $47$.


Sample Input 2

10
180 168 120 144 192 200 198 160 156 150
1 2
2 3
2 4
2 5
5 6
4 7
7 8
7 9
9 10

Sample Output 2

1184

两个东西乘起来,很不好算。我们尝试拆开来算,就是枚举一个,求另一个的和。

路径数量和 gcd,看起来枚举gcd更容易。为了方便,设一个边 \((u,v)\) 的边权为 \(\gcd(a_u,a_v)\),这样也好加边。设现在枚举,令 \(k\) 为枚举到的最小公因数,一个很自然的想法就是把所有 \(a\) 为 \(k\) 的倍数的边拎出来,组成一棵树,然后跑一个 dp。考虑一条边 \((u,v,w)\),那么 \(w\) 的因数个数就是他会被计算的次数,因数个数 \(\sqrt{w}\) 个,所以如果能保证dp和建树是严格 \(O(n)\),最终复杂度是 \(O(n\sqrt{n})\)

先来看一下怎么dp。现在给出一棵树,我们要求所有路径长度之和。首先可以每个连通块单独考虑。定义 \(dp_i\) 为所有树上以 \(i\) 为端点的路径之和, \(c_i\) 为 \(i\) 为根的子树大小。那么 \(dp_v\) 转移到 \(dp_i\) 时,共有 \(c_v\) 个路径,他们长度全部增加1。算最终答案时,目前的 \(dp_i\) 会有多 \(c_v\) 个, \(dp_v\) 会多目前的 \(c_i\) 个。

但是我们发现这样算出来的答案不完全对。因为我们并不能保证这些路径的 \(\gcd\) 为 \(k\),只能保证他是 \(k\) 的倍数。我们可以用筛法处理出一个容斥系数。因为我在算 \(k\) 的答案一定算了 \(2k\) 的答案,在 \(2k\) 时容斥系数要减去那么多。

总复杂度 \(O(n\sqrt{n)\)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,P=998244353;
int n,a[N],u[N],vis[N],e_num,hd[N],ret,ans,c[N],dp[N],p[N],fp[N],v[N];
struct edge{
int v,nxt;
}e[N<<1];
vector<int>g[N],f[N];
void add_edge(int u,int v)
{
e[++e_num]=(edge){v,hd[u]};
hd[u]=e_num;
}
int gcd(int x,int y)
{
if(!y)
return x;
return gcd(y,x%y);
}
void dfs(int x,int y)
{
// printf("%d %d\n",x,y);
vis[x]=0;
dp[x]=c[x]=1;
fp[x]=0;
for(int i=hd[x];i;i=e[i].nxt)
{
if(e[i].v==y)
continue;
dfs(e[i].v,x);
int ac=c[x],ad=dp[x];
int bc=c[e[i].v],bd=dp[e[i].v];
(fp[x]+=(1LL*ad*bc%P+1LL*ac*bd%P)%P)%=P;
(fp[x]+=fp[e[i].v])%=P;
(dp[x]+=(bc+bd)%P)%=P;
(c[x]+=bc)%=P;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
for(int i=1;i<N;i++)
for(int j=1;j*i<N;j++)
g[i*j].push_back(i);
for(int i=1;i<n;i++)
{
scanf("%d%d",u+i,v+i);
int w=gcd(a[u[i]],a[v[i]]);
for(int j=0;j<g[w].size();j++)
f[g[w][j]].push_back(i);
}
for(int i=1;i<N;i++)
{
p[i]+=i;
for(int j=2;1LL*j*i<N;j++)
p[j*i]-=p[i];
e_num=0;
for(int j=0;j<f[i].size();j++)
{
int x=u[f[i][j]],y=v[f[i][j]];
add_edge(x,y);
add_edge(y,x);
vis[x]=vis[y]=1;
}
for(int j=0;j<f[i].size();j++)
{
int x=u[f[i][j]];
if(vis[x])
{
dfs(x,0);
(ans+=(1LL*fp[x]%P*p[i]%P))%=P;
}
}
for(int j=0;j<f[i].size();j++)
{
int x=u[f[i][j]],y=v[f[i][j]];
hd[x]=hd[y]=0;
}
// for(int i=1;i<=n;i++)
// printf("%d ",fp[i]);
// putchar('\n');
}
printf("%d",ans);
}

[ABC248G] GCD cost on the tree的更多相关文章

  1. Codeforces Round #527 (Div. 3) F. Tree with Maximum Cost 【DFS换根 || 树形dp】

    传送门:http://codeforces.com/contest/1092/problem/F F. Tree with Maximum Cost time limit per test 2 sec ...

  2. CF1092 --- Tree with Maximum Cost

    CF1324 --- Maximum White Subtree 题干 You are given a tree consisting exactly of \(n\) vertices. Tree ...

  3. POJ3013 Big Christmas Tree[转换 最短路]

    Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 23387   Accepted: 5 ...

  4. Color a Tree[HDU1055]

    Color a Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  5. poj 3013 Big Christmas Tree (最短路径Dijsktra) -- 第一次用优先队列写Dijsktra

    http://poj.org/problem?id=3013 Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total S ...

  6. poj 3013 Big Christmas Tree

    Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 20974   Accepted: 4 ...

  7. Big Christmas Tree(poj-3013)最短路

    Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 25823   Accepted: 5 ...

  8. hdu-3071 Gcd & Lcm game---质因数分解+状态压缩+线段树

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3071 题目大意: 给定一个长度为n的序列m次操作,操作的种类一共有三种 查询 L :查询一个区间的所 ...

  9. HDU 2196 Computer 树形DP 经典题

    给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...

  10. HDU 5861 Road (线段树)

    Road 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Description There are n villages alo ...

随机推荐

  1. langchain中的LLM模型使用介绍

    简介 构建在大语言模型基础上的应用通常有两种,第一种叫做text completion,也就是一问一答的模式,输入是text,输出也是text.这种模型下应用并不会记忆之前的问题内容,每一个问题都是最 ...

  2. github.com/yuin/gopher-lua 踩坑日记

    本文主要记录下在日常开发过程中, 使用 github.com/yuin/gopher-lua 过程中需要注意的地方. 后续遇到其他的需要注意的事项再补充. 1.加载LUA_PATH环境变量 在实际开发 ...

  3. Deep Transfer Learning综述阅读笔记

    这是一篇linkedin发表的深度迁移学习综述, 里面讲了一些对于search/recommend system中的迁移学习应用. 有不少指导性的方法, 看完后摘录出来 对于ranking方向的TL, ...

  4. 【项目源码】基于JavaEE的健康管理系统

    随着网络技术的不断发展,网站的开发与运用变得更加广泛.这次采用java语言SSH框架(Spring,Struts,Hibernate)设计并实现了面向特定群体的健康管理平台.该网站主要有教师饮食管理. ...

  5. 一文搞懂 OTP 双因素认证

    GitHub 在 2023 年 3 月推出了双因素认证(two-factor authentication)简称 2FA,并且承诺所有在 GitHub 上贡献的开发者在 2023 年底前启用双因素认证 ...

  6. mpi转以太网连接200PLC转以太网modbusTCP服务器通信配置方法

    兴达易控200PLC转以太网modbusTCP服务器通信配置方法 产品简介 兴达易控PPI-ETH-XD1.0用于西门子S7-200/SMART S7-200PLC的以太网数据采集,非常方便构建生产管 ...

  7. centos7.9 扩容swap分区

    情况说明:在VMware vsphere的虚拟化平台下,为了快速部署虚拟服务器,我们常常使用模板部署虚拟机.但真实业务有时要求的文件系统分区和大小常常与模板不同,这时便需要自定义硬件资源和使用 LVM ...

  8. DotNetGuide新增C#/.NET/.NET Core充电站(让你学习不迷路)

    DotNetGuide简介 记录.收集和总结C#/.NET/.NET Core基础知识.学习路线.开发实战.学习视频.文章.书籍.项目框架.社区组织.开发必备工具.常见面试题.面试须知.简历模板.以及 ...

  9. 解密Prompt系列16. LLM对齐经验之数据越少越好?LTD & LIMA & AlpaGasus

    LLM Agent中间插个队,总结下指令微调.对齐数据相关的方案,已经凑够7篇论文可以召唤神龙啦!论文都是以优化指令样本为核心,Data-Centric的观点比较一致:指令微调也就是对齐阶段的数据质量 ...

  10. MySQL5.7版本单节点大数据量迁移到PXC8.0版本集群全记录-3

    接上文,单节点升级到80版本之后,构建新版本的80集群就水到渠成.相对简单了,详情可参见之前的集群构建博文. 本文在修改配置集群的新参数时,修改了pxc_strict_mode为默认的ENFORCIN ...