题目大意:给定一棵有根树,边长均为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的更多相关文章

  1. [UOJ UR #2]树上GCD

    来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 看完题目,一般人都能想到 容斥稳了 .这样我们只要统计有多少点对满足gcd是i的倍数. 考虑长链剖分,每次合并的时候,假设我已经求出轻 ...

  2. 【uoj33】 UR #2—树上GCD

    http://uoj.ac/problem/33 (题目链接) 题意 给出一棵${n}$个节点的有根树,${f_{u,v}=gcd(dis(u,lca(u,v)),dis(v,lca(u,v)))}$ ...

  3. UOJ33 [UR #2] 树上GCD 【点分治】【容斥原理】【分块】

    题目分析: 树上点对问题首先想到点分治.假设我们进行了点分治并递归地解决了子问题.现在我们合并问题. 我们需要找到所有经过当前重心$ c $的子树路径.第一种情况是LCA为当前重心$ c $.考虑以$ ...

  4. 【UOJ#33】【UR#2】树上GCD 有根树点分治 + 容斥原理 + 分块

    #33. [UR #2]树上GCD 有一棵$n$个结点的有根树$T$.结点编号为$1…n$,其中根结点为$1$. 树上每条边的长度为$1$.我们用$d(x,y)$表示结点$x,y$在树上的距离,$LC ...

  5. 【UOJ#33】【UR #2】树上GCD(长链剖分,分块)

    [UOJ#33][UR #2]树上GCD(长链剖分,分块) 题面 UOJ 题解 首先不求恰好,改为求\(i\)的倍数的个数,最后容斥一下就可以解决了. 那么我们考虑枚举一个\(LCA\)位置,在其两棵 ...

  6. UOJ#33. 【UR #2】树上GCD 点分治 莫比乌斯反演

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ33.html 题解 首先我们把问题转化成处理一个数组 ans ,其中 ans[i] 表示 d(u,a) 和 ...

  7. UOJ#33-[UR #2]树上GCD【长链剖分,根号分治】

    正题 题目链接:https://uoj.ac/problem/33 题目大意 给出\(n\)个点的一棵树 定义\(f(x,y)=gcd(\ dis(x,lca),dis(y,lca)\ )\). 对于 ...

  8. 【UR #2】树上GCD

    这道题是有根树点分治+烧脑的容斥+神奇的分块 因为是规定1为根,还要求LCA,所以我们不能像在无根树上那样随便浪了,必须规定父亲,并作特殊讨论 因为gcd并不好求,所以我们用容斥转化一下,求x为gcd ...

  9. uoj33 【UR #2】树上GCD

    题目 大致是长剖+\(\rm dsu\ on\ tree\)的思想 先做一个转化,改为对于\(i\in[1,n-1]\)求出有多少个\(f(u,v)\)满足\(i|f(u,v)\),这样我们最后再做一 ...

随机推荐

  1. 201621123040《Java程序设计》第十一周学习总结

    1.本周学习总结 1.1以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2.书面作业 2.1源代码阅读:多线程程序BounceThread 2.1.1BallRunnable类有什么用?为什 ...

  2. 高级软件工程2017第6次作业--团队项目:Alpha阶段综合报告

    高级软件工程2017第6次作业--团队项目:Alpha阶段综合报告 Deadline:2017-10-30(周一)21:00pm (注:以下内容参考集大作业4,集大作业5,集大作业6,集大作业7 一. ...

  3. Flask学习 二 模板

    jinja2模版 from flask import Flask,render_template app = Flask (__name__) @app.route ('/<name>') ...

  4. vue初尝试--项目结构

    新建一个项目之后,我们来看一下项目的目录结构 几个主要文件的内容 index.html文件(入口文件,系统进入之后先进入index.html) <!DOCTYPE html> <ht ...

  5. 【微软大法好】VS Tools for AI全攻略

    大家都知道微软在Connect();17大会上发布了VS Tools for AI,旨在提升Visual Studio和VSCode对日益增长的深度学习需求的体验.看了一圈,网上似乎没有一个完整的中文 ...

  6. 基于RNN的音频降噪算法 (附完整C代码)

    前几天无意间看到一个项目rnnoise. 项目地址: https://github.com/xiph/rnnoise 基于RNN的音频降噪算法. 采用的是 GRU/LSTM 模型. 阅读下训练代码,可 ...

  7. kubernetes入门(04)kubernetes的核心概念(1)

    一.ReplicationController/ReplicaSet 在Kubernetes集群中,ReplicationController能够确保在任意时刻,指定数量的Pod副本正在运行.如果Po ...

  8. word2vec初探(用python简单实现)

    为什么要用这个? 因为看论文和博客的时候很常见,不论是干嘛的,既然这么火,不妨试试. 如何安装 从网上爬数据下来 对数据进行过滤.分词 用word2vec进行近义词查找等操作 完整的工程传到了我的gi ...

  9. ccf认证 201709-4 通信网络 java实现

    试题编号:                                                               201709-4 试题名称: 通信网络 时间限制: 1.0s 内 ...

  10. 计算机基础,Python基础--变量以及简单的循环

    一.计算机基础 1.CPU 相当于人体的大脑,用于计算处理数据. 2.内存  用于存储数据,CPU从内存调用数据处理计算,运算速度很快. PS:问:既然在内存里的数据CPU运算速度快,为什么计算机不全 ...