码迷,mamicode.com
首页 > Windows程序 > 详细

BC#40D GCD值统计

时间:2015-05-11 10:30:08      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:

这题有点恶心,好多东西堆一起。刚开始看出来实质就是SG,于是很开心的敲了,然后发现统计GCD很烦,推了半天以为推出来了,写完后到最后一步,只想到暴力遍历。提交后TLE,倒回来想树上任意路径权值和的问题,这不是裸的树分治么,以前一眼能看出来的。只是最后再加个树分治略恶心。第二天早上突然发觉,统计GCD值的地方,实际上是n^2.5的,脑残了,复杂度都算不准了。问题实质就是:

∑(n,i=1)∑(m,j=1)gcd(i,j)=∑(n,i=1)∑(m,j=1)∑(d|i&d|j)?(d)=∑(min(n,m),d=1)?(d)n/dm/d

这里不能插入公式,把∑的上下界用括号括起来了,实质就是求(1~n)和(1~m)范围内的任意i和j的最大公约数之和。可以预处理,值的范围为10^4,给10^4个这种查询,要求sqrt(n)的复杂度内求解一次查询。

首先一个变换为gcd(i,j)=∑(d|i&d|j)?(d),就是i,j的最大公约数为他两的所有约数的欧拉函数值之和。这样就不用去重、容斥什么的了。然后对于每个约数d在(1,n)范围内的数中有n/d个包含约数d,同理(1,m)中有m/d个,所以得到上面那个式子。

最后问题就变成∑(min(n,m),d=1)?(d)n/dm/d了。因为n/d和m/d的结果最多有sqrt(n)级别的不同的值,所以可以处理出这些值,得到对应的区间段,对于n/d的有sqrt(n)段,m/d有sqrt(m)段,将他们两的区间段合并最多有sqrt(n)+sqrt(m)段,对于每段中的值x,n/x的值的一样的,m/x的值也是一样的,

所以可以统一求解,预处理?(d)的前缀和,一次查询复杂度为sqrt(n)级别。

 

BC#40D GCD值统计

标签:

原文地址:http://www.cnblogs.com/seen1020/p/4493792.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!