[ABC248G] GCD cost on the tree
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的更多相关文章
- 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 ...
- CF1092 --- Tree with Maximum Cost
CF1324 --- Maximum White Subtree 题干 You are given a tree consisting exactly of \(n\) vertices. Tree ...
- POJ3013 Big Christmas Tree[转换 最短路]
Big Christmas Tree Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 23387 Accepted: 5 ...
- Color a Tree[HDU1055]
Color a Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- poj 3013 Big Christmas Tree (最短路径Dijsktra) -- 第一次用优先队列写Dijsktra
http://poj.org/problem?id=3013 Big Christmas Tree Time Limit: 3000MS Memory Limit: 131072K Total S ...
- poj 3013 Big Christmas Tree
Big Christmas Tree Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 20974 Accepted: 4 ...
- Big Christmas Tree(poj-3013)最短路
Big Christmas Tree Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 25823 Accepted: 5 ...
- hdu-3071 Gcd & Lcm game---质因数分解+状态压缩+线段树
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3071 题目大意: 给定一个长度为n的序列m次操作,操作的种类一共有三种 查询 L :查询一个区间的所 ...
- HDU 2196 Computer 树形DP 经典题
给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...
- HDU 5861 Road (线段树)
Road 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Description There are n villages alo ...
随机推荐
- 2023-08-20:用go语言写算法。给定一个由'W'、'A'、'S'、'D'四种字符组成的字符串,长度一定是4的倍数, 你可以把任意连续的一段子串,变成'W'、'A'、'S'、'D'组成的随意状
2023-08-20:用go语言写算法.给定一个由'W'.'A'.'S'.'D'四种字符组成的字符串,长度一定是4的倍数, 你可以把任意连续的一段子串,变成'W'.'A'.'S'.'D'组成的随意状态 ...
- [Bread.Mvc] 开源一款自用 MVC 框架,支持 Native AOT
Bread.Mvc Bread.Mvc 是一款完全支持 Native AOT 的 MVC 框架,搭配同样支持 AOT 的 Avalonia,让你的开发事半功倍.项目开源在 Gitee,欢迎 Star. ...
- dedebiz实时时间调用
{dede:tagname runphp='yes'}@me = date("Y-m-d H:i:s", time());{/dede:tagname}
- Solution -「香港网络赛 2016」A+B Problem
Description Link. 给出一个长度为 \(n\) 的序列 \(a\),问有序三元组 \((a_{i},a_{j},a_{k})\) 使得 \(i\neq j\neq k\) 且 \(a_ ...
- containerd镜像拉取配置
背景: 公司要求部署最一套新版的k8s系统来部署生产应用,说实话很头疼.因为k8s自1.23版本之后就用不docker作为容器的默认运行时了,而是采用的containerd,这就带来了一系列的问题.没 ...
- Oracle:查询表的统计信息,手动收集统计信息
在Oracle中,存在执行计划不准的情况,怀疑表的统计信息是否收集,需要以下操作:select table_name,num_rows,blocks,last_analyzed from user_t ...
- HexConversion 二进制 八进制 十六进制 十进制
public class HexConversion { // TODO Auto-generated method stub /** * TODO 进制转换. * * @param cc * htt ...
- svn: E200007: Retrieval of mergeinfo unsupported解决
http://blog.csdn.net/intlgj/article/details/39080605 svn: E200007: Retrieval of mergeinfo unsupport ...
- python接口自动化 之excel读取测试数据
一.当你拥有一个excel版的接口用例 excel中有用例名称.url.请求方式和请求参数 二.获取excel的Url.请求方式和请求参数 # 单独获取某个单元格的值,第二行第二列# 第二行数据 ro ...
- Treap树学习笔记
等我写完. 普通fhq treap: enum { Maxn = 1000005 }; struct FHQTreap { int lson[Maxn], rson[Maxn], data[Maxn] ...