正题

题目链接:https://uoj.ac/problem/33


题目大意

给出nnn个点的一棵树

定义f(x,y)=gcd(dis(x,lca),dis(y,lca))f(x,y)=gcd(\ dis(x,lca),dis(y,lca)\ )f(x,y)=gcd( dis(x,lca),dis(y,lca) )。

对于每个iii求有多少对f(x,y)=i(x<y)f(x,y)=i(x<y)f(x,y)=i(x<y)

1≤n≤1051\leq n\leq 10^51≤n≤105


解题思路

首先肯定是枚举lcalcalca节点,然后看他子树里的情况,比较麻烦的是gcdgcdgcd刚刚好是ddd,但是其实我们可以是ddd的倍数的情况,然后后面再容斥出答案。

如果,然后暴力算的话首先需要一个长链剖分,然后每次是lenloglenlen\ log\ lenlen log len的。

但是仔细想一想就会发现这个复杂度其实是假的,因为每次暴力算的话的lenlenlen是这条链上面那条链的lenlenlen。

考虑点其他做法,因为是枚举倍数,我们可以上我们的根号分治

对于dis>ndis>\sqrt ndis>n​的情况,我们之间暴力枚举倍数,因为这样不会超过n\sqrt nn​次

对于dis≤ndis\leq \sqrt ndis≤n​的情况,我们考虑储存一些东西,设gi,jg_{i,j}gi,j​表示当前的链中depdepdep模iii为jjj的点的个数,然后处理的时候我们就可以直接用这个来计算了。

这样平衡下来时间复杂度就是O(nn)O(n\sqrt n)O(nn​)了


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
using namespace std;
const int N=2e5+10;
struct node{int to,next;
}a[N];
int n,T,len[N],dep[N],h[N],g[400][400];
int tot,t[N],ls[N],son[N],*f[N],*now;
long long ans[N],pre[N];
int read(){int x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
void addl(int x,int y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;
}
void dfs(int x){for(int i=ls[x];i;i=a[i].next){int y=a[i].to;dep[y]=dep[x]+1;dfs(y);if(len[y]>len[son[x]])son[x]=y;}len[x]=len[son[x]]+1;return;
}
void calc(int x,int top){f[x][0]=1;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==son[x])continue;f[y]=now;now+=len[y];calc(y,y);}if(son[x]){f[son[x]]=f[x]+1;calc(son[x],top);}for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==son[x])continue;for(int j=1;j<=len[y];j++)t[j]=f[y][j-1];for(int j=1;j<=len[y];j++)for(int k=2*j;k<=len[y];k+=j)t[j]+=t[k];for(int j=1;j<=len[y];j++)if(j>T){for(int k=j;k<len[x];k+=j)ans[j]+=1ll*f[x][k]*t[j];}else ans[j]+=1ll*g[j][dep[x]%j]*t[j];for(int j=1;j<=len[y];j++)f[x][j]+=f[y][j-1];for(int j=0;j<len[y];j++)for(int k=1;k<=T;k++)g[k][(j+dep[y])%k]+=f[y][j];}for(int i=1;i<=T;i++)g[i][dep[x]%i]++;if(x==top){for(int i=1;i<=T;i++)for(int j=0;j<len[x];j++)g[i][(j+dep[x])%i]=0;}return;
}
signed main()
{n=read();for(int i=2;i<=n;i++)addl(read(),i);dfs(1);T=sqrt(n);if(T>350)T=350;f[1]=now=h;now+=len[1];calc(1,1);for(int i=n;i>=1;i--)for(int j=2*i;j<=n;j+=i)ans[i]-=ans[j];for(int i=2;i<=n;i++)pre[dep[i]]++;for(int i=n;i>=1;i--)pre[i]+=pre[i+1];for(int i=1;i<n;i++)printf("%lld\n",ans[i]+pre[i]);return 0;
}

UOJ#33-[UR #2]树上GCD【长链剖分,根号分治】相关推荐

  1. 【UOJ#33】【UR #2】树上GCD(长链剖分/根号分类讨论)

    [UOJ#33][UR #2]树上GCD 求解树上两个点到lca的距离的最大公约数是k的对数 首先我们很容易就想到莫比乌斯反演,那么利用倍数形式,我们只需要求解是i的倍数的对数. 考虑枚举lca,这个 ...

  2. UOJ#284-快乐游戏鸡【长链剖分,线段树】

    正题 题目链接:https://uoj.ac/problem/284 题目大意 nnn个点的一棵树,每个点有一个wiw_iwi​表示至少死亡wiw_iwi​次才能通过这个点,否则就会死亡.只能往子节点 ...

  3. Bzoj4016/洛谷P2993 [FJOI2014] 最短路径树问题(最短路径问题+长链剖分/点分治)

    题面 Bzoj 洛谷 题解 首先把最短路径树建出来(用\(Dijkstra\),没试过\(SPFA\)\(\leftarrow\)它死了),然后问题就变成了一个关于深度的问题,可以用长链剖分做,所以我 ...

  4. UOJ284 快乐游戏鸡(树上动态规划问题、长链剖分+单调栈)

    Description 一棵 n 个点的有根树,带点权 wi. 从 s 出发,希望达到 t,每秒可以从当前点移动到某一个儿子. 有一个死亡次数,初始为 0.若在某个点 i(i != s, t) 时,死 ...

  5. hdu 4607 Park Visit(树上最长链)

    求树上最长链:两遍搜索. 第一次从树上任意点开始,最远点必然是某一条最长链上的端点u. 第二次从u开始,最远点即该最长链的另一端点. 先在最长链上走,不足再去走支链. 把询问数m错打成n,狠狠wa了一 ...

  6. [树上最长链][tarjan][单调队列][环上前缀和] Jzoj P5905 黑暗之魂(darksoul)

    Description oi_juruo热爱一款名叫黑暗之魂的游戏.在这个游戏中玩家要操纵一名有 点生命值的无火的余灰在一张地图中探险.地图中有n个篝火(也就是存档点).在篝火处休息可以将生命值恢复满 ...

  7. 1577 例题3 数字转换(LOJ10155) 约数计算 树上最长链(两次找最大深度)

    总目录 在线测评地址(ybt) 在线测评地址(LOJ) 发现竟然读不懂题.努力静下来,再读题,总算有了眉目. 4→3→1→74的约数,不包括本身,1,2,约数和是1+2=3, 3的约数,不包括本身,1 ...

  8. 【luogu P5903】【模板】树上 k 级祖先(长链剖分)

    [模板]树上 k 级祖先 题目链接:luogu P5903 题目大意 给你一棵树,要你在线 O(1) 求一个点的 k 级祖先. 思路 这个我们可以用长链剖分来做,从而可以做到预处理 O ( n log ...

  9. 对LCA、树上倍增、树链剖分(重链剖分长链剖分)和LCT(Link-Cut Tree)的学习

    LCA what is LCA & what can LCA do LCA(Lowest Common Ancestors),即最近公共祖先 在一棵树上,两个节点的深度最浅的公共祖先就是 L ...

最新文章

  1. Ubuntu 12.04安装Sun JDK 6
  2. 小P寻宝记——好基友一起走 背包
  3. ios证书导出不了p12文件_IOS苹果证书无法生成.P12文件解决方法
  4. python有道翻译接口-【Python】Python利用有道翻译开发API应用示例
  5. 再说 Spring AOP
  6. sqlserver查看跟某个表相关的所有存储过程
  7. java 打包下载文件_java下载打包下载文件
  8. 产品铭牌要求_AMPULM:电力变压器铭牌有哪些主要技术参数,你都知道吗?
  9. FreeModbus移植到STM32F103(串行传输方式)
  10. 蒙特卡洛方法_程序媛转TA之理论篇十三:蒙特卡洛方法
  11. 干货!286页李宏毅《深度学习讲义》
  12. 2021年下半年网络工程师上午真题及答案解析
  13. 转]Linux杀死进程方法大全
  14. [Ceoi2010]Pin
  15. ssis for循环容器_SSIS包中的序列容器
  16. 在windows server 2003服务器上提供NTP时间同步服务
  17. 【GEE】配置本地python环境
  18. vsftpd配置详解
  19. 二阶微分方程解法总结 Summary of Second Order Equations
  20. 映美精LoadDeviceStateFromFile问题

热门文章

  1. matlab作业1参考答案,matlab课后习题答案1到6章
  2. aggregation java_Elasticsearch Aggregation 多个字段分组统计 Java API实现
  3. linux ll 转数组,List、Set、数组之间的转换
  4. d.ts文件可以注释html吗,如何编写一个d.ts文件的步骤详解_旧店_前端开发者
  5. html站点如何命名,html页面的CSS、DIV命名规则
  6. mysql 8 配置参数优化_mysql8 参考手册--配置非持久性优化器统计参数
  7. idea怎么把代码放到git_在IDEA中如何初始化Git,把项目推送到Git上
  8. 78. 子集022(回溯法)
  9. C++ 学习之旅(10)——static与extern
  10. 「offer来了」2种递进学习思维,24道计网题目,保姆级巩固你的计网知识体系