[UOJ]#33. 【UR #2】树上GCD
题目大意:给定一棵有根树,边长均为1,对于每一个i,求树上有多少个点对,他们到lca距离的gcd是i。(n<=200,000)
做法:先容斥,求出gcd是i的倍数的点对,考虑长链剖分后从小到大合并计算答案,小的部分先把每个深度的数量变为每个深度的倍数的数量,然后若深度>k,直接到大的里面暴力,若深度<=k,我们在大的里面维护f[i][j]表示深度mod i(1<=i<=k)为j的点数,理论上k取n^0.5时达到最小复杂度O(n^1.5),实际上k比较小的时候常数较小。另外递归计算的时候先递归轻儿子,这样始终都只要存一个f数组。
代码:
#include<cstdio>
inline int read()
{
int x;char c;
while((c=getchar())<''||c>'');
for(x=c-'';(c=getchar())>=''&&c<='';)x=x*+c-'';
return x;
}
#define MN 200000
#define K 20
struct edge{int nx,t;}e[MN+];
int h[MN+],en,d[MN+],ht[MN+],mx[MN+],l[MN+],cnt;
int f[MN+],c[MN+],s[K+][K+];
long long ans[MN+],ss[MN+];
inline void ins(int x,int y){e[++en]=(edge){h[x],y};h[x]=en;}
void dfs(int x)
{
l[x]=++cnt;
if(mx[x])dfs(mx[x]);
for(int i=h[x];i;i=e[i].nx)if(e[i].t!=mx[x])dfs(e[i].t);
}
void solve(int x,int v)
{
for(int i=h[x];i;i=e[i].nx)if(e[i].t!=mx[x])solve(e[i].t,);
if(mx[x])solve(mx[x],);
for(int i=h[x];i;i=e[i].nx)if(e[i].t!=mx[x])
{
for(int j=;j<=ht[e[i].t];++j)
{
c[j]=f[l[e[i].t]+j];
for(int k=j;(k+=j+)<=ht[e[i].t];)f[l[e[i].t]+j]+=f[l[e[i].t]+k];
if(j<K)ans[j+]+=1LL*f[l[e[i].t]+j]*s[j+][d[x]%(j+)];
else for(int k=;(k+=j+)<=ht[x];)ans[j+]+=1LL*f[l[e[i].t]+j]*f[l[x]+k];
}
for(int j=;j<=ht[e[i].t];++j)
{
f[l[x]+j+]+=c[j];
for(int k=;k<=K;++k)s[k][(d[e[i].t]+j)%k]+=c[j];
}
}
f[l[x]]=;
if(v)for(int i=;i<=ht[x];++i)for(int k=;k<=K;++k)s[k][(d[x]+i)%k]-=f[l[x]+i];
else for(int k=;k<=K;++k)++s[k][d[x]%k];
}
int main()
{
int n=read(),i,j;
for(i=;i<=n;++i)++ss[d[i]=d[j=read()]+],ins(j,i);
for(i=n;i;--i)for(j=h[i];j;j=e[j].nx)
if(ht[e[j].t]+>ht[i])ht[i]=ht[mx[i]=e[j].t]+;
dfs();solve(,);
for(i=n;i;--i)for(ss[j=i]+=ss[i+];(j+=i)<=n;)ans[i]-=ans[j];
for(i=;i<n;++i)printf("%lld\n",ans[i]+ss[i]);
}
[UOJ]#33. 【UR #2】树上GCD的更多相关文章
- [UOJ UR #2]树上GCD
来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 看完题目,一般人都能想到 容斥稳了 .这样我们只要统计有多少点对满足gcd是i的倍数. 考虑长链剖分,每次合并的时候,假设我已经求出轻 ...
- 【uoj33】 UR #2—树上GCD
http://uoj.ac/problem/33 (题目链接) 题意 给出一棵${n}$个节点的有根树,${f_{u,v}=gcd(dis(u,lca(u,v)),dis(v,lca(u,v)))}$ ...
- UOJ33 [UR #2] 树上GCD 【点分治】【容斥原理】【分块】
题目分析: 树上点对问题首先想到点分治.假设我们进行了点分治并递归地解决了子问题.现在我们合并问题. 我们需要找到所有经过当前重心$ c $的子树路径.第一种情况是LCA为当前重心$ c $.考虑以$ ...
- 【UOJ#33】【UR#2】树上GCD 有根树点分治 + 容斥原理 + 分块
#33. [UR #2]树上GCD 有一棵$n$个结点的有根树$T$.结点编号为$1…n$,其中根结点为$1$. 树上每条边的长度为$1$.我们用$d(x,y)$表示结点$x,y$在树上的距离,$LC ...
- 【UOJ#33】【UR #2】树上GCD(长链剖分,分块)
[UOJ#33][UR #2]树上GCD(长链剖分,分块) 题面 UOJ 题解 首先不求恰好,改为求\(i\)的倍数的个数,最后容斥一下就可以解决了. 那么我们考虑枚举一个\(LCA\)位置,在其两棵 ...
- UOJ#33. 【UR #2】树上GCD 点分治 莫比乌斯反演
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ33.html 题解 首先我们把问题转化成处理一个数组 ans ,其中 ans[i] 表示 d(u,a) 和 ...
- UOJ#33-[UR #2]树上GCD【长链剖分,根号分治】
正题 题目链接:https://uoj.ac/problem/33 题目大意 给出\(n\)个点的一棵树 定义\(f(x,y)=gcd(\ dis(x,lca),dis(y,lca)\ )\). 对于 ...
- 【UR #2】树上GCD
这道题是有根树点分治+烧脑的容斥+神奇的分块 因为是规定1为根,还要求LCA,所以我们不能像在无根树上那样随便浪了,必须规定父亲,并作特殊讨论 因为gcd并不好求,所以我们用容斥转化一下,求x为gcd ...
- uoj33 【UR #2】树上GCD
题目 大致是长剖+\(\rm dsu\ on\ tree\)的思想 先做一个转化,改为对于\(i\in[1,n-1]\)求出有多少个\(f(u,v)\)满足\(i|f(u,v)\),这样我们最后再做一 ...
随机推荐
- [W班]第二次结对作业成绩评价
作业地址: https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1715W/homework/1016 作业要求: 1.代码具有规范性. ...
- Linux下ftp和ssh详解
学习了几天Linux下ftp和ssh的搭建和使用,故记录一下.学习ftp和ssh的主要目的是为了连接远程主机,并且进行文件传输.废话不多说,直接开讲! ftp服务器 1. 环境搭建 本人的系统是Arc ...
- bzoj千题计划113:bzoj1023: [SHOI2008]cactus仙人掌图
http://www.lydsy.com/JudgeOnline/problem.php?id=1023 dp[x] 表示以x为端点的最长链 子节点与x不在同一个环上,那就是两条最长半链长度 子节点与 ...
- js实现短暂提示框
业务场景:当鼠标移入某元素时,显示提示框进行介绍.当鼠标移除时,会自动消失.引入ToolTip.js和ToolTip.css 主方法:ToolTip.show(需要提示的元素id, 随意不重复即可, ...
- LeetCode & Q38-Count and Say-Easy
String Description: The count-and-say sequence is the sequence of integers with the first five terms ...
- SpringCloud的DataRest(三)
一.进阶配置定义 二.定制显示内容和控制方法使用 1.控制显示的内容 如果想让输出显示的数据始终按我们定义的格式显示: 配置之后返回的JSON数据会按照ListApp定义的数据格式进行输出 2.屏蔽自 ...
- Docker学习笔记 - Docker的镜像
一个容器实际上是运行在宿主机上的一个进程. 只不过在启动这个进程之前进行了一些特殊处理,让这个容器进入了一个全新的虚拟环境,与宿主机的环境分开, 所以这个进程及其子进程认为自己运行在一个独立的世界里面 ...
- 实现一个网易云音乐的 BottomSheetDialog
作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...
- Python之匿名函数
匿名函数 匿名函数:为了解决那些功能很简单的需求而设计的一句话函数. #这段代码 def calc(n): return n**n print(calc(10)) #换成匿名函数 calc = lam ...
- Java设计模式(八)Proxy代理模式
一.场景描述 代理在生活中并不少见,租房子需要找中介,打官司需要找律师,很多事情我们需要找专业人士代理我们做,另一方面,中介和律师也代理了房东.法律程序与我们打交道. 当然,设计模式中的代理与广义的代 ...