【51Nod1584】加权约数和(数论)

题面

51Nod

题解

要求的是$$\sum_{i=1}n\sum_{j=1}n max(i,j)\sigma(ij)$$

这个\(max\)太讨厌了,直接枚举一半乘个二。

\[2\sum_{i=1}^n\sum_{j=1}^{i}i\sigma(ij)-\sum_{i=1}^ni\sigma(i^2)
\]

后面这一半可以直接预处理,只需要把\(i\)分解,可以做到调和级数的复杂度。

只考虑前面这一半,显然只需要考虑的是\(\sigma(ij)\)这个东西。

那么我们考虑在\(i\)中枚举一个约数,在\(j\)中枚举一个约数,然后把这两个约数合并一下,看看能不能让每个约数只被计算一次。

\[\sigma(ij)=\sum_{u|i}\sum_{v|j}[gcd(u,\frac{j}{v})=1]uv
\]

证明的话,大概就是我们的目标是让每个约数只被计算一次,首先在\(i\)中枚举一个约数肯定没有问题,在\(j\)中枚举一个质因数也没有问题。对于\(uv\)这个数而言,我们把只在\(i\)中有的因子和只在\(j\)中有的因子给丢掉,只考虑在\(i,j\)中都含有的因子\(u',v'\),对于一个数\(uv\)而言,可能算重的情况是\(u'\)从\(v'\)那里抢走了一个质因子,而此时\(\frac{j}{v}\)就会对应的乘上那个质因子,使得\(gcd\neq 1\),所以每个数只会被计算一次。

有了这个式子就很好搞了,首先把这个式子换一个形式:

\[\sigma(ij)=\sum_{u|i}\sum_{v|j}[gcd(u,v)=1]\frac{uj}{v}
\]

带回去得到:

\[\sum_{i=1}^n i\sum_{j=1}^i\sum_{u|i}\sum_{v|j}[gcd(u,v)=1]\frac{uj}{v}
\]

考虑对于每一个\(i\)分别计算答案,所以我们设

\[\begin{aligned}
f[n]&=n\sum_{j=1}^n\sum_{u|n}\sum_{v|j}[gcd(u,v)=1]\frac{uj}{v}\\
&=n\sum_{j=1}^n \sum_{u|n}\sum_{v|j}\frac{uj}{v}\sum_{k|u,k|v}\mu(k)\\
&=n\sum_{j=1}^n\sum_{k|n,k|j}\mu(k)\sum_{k|u,u|n}\sum_{k|v,v|j}\frac{uj}{v}\\
&=n\sum_{j=1}^n\sum_{k|n,k|j}\mu(k)(k\sigma(\frac{n}{k}))\sigma(\frac{j}{k})\\
&=n\sum_{k|n}\mu(k)k\sigma(\frac{n}{k})\sum_{i=1}^{n/k}\sigma(i)
\end{aligned}\]

然后就是前缀和计算就行了。

所有东西可以线性筛,中间要求逆就直接快速幂了。。。。

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. #define ll long long
  5. #define MOD 1000000007
  6. #define MAX 1000100
  7. inline int read()
  8. {
  9. int x=0;bool t=false;char ch=getchar();
  10. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  11. if(ch=='-')t=true,ch=getchar();
  12. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  13. return t?-x:x;
  14. }
  15. int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
  16. bool zs[MAX];
  17. int pri[MAX],tot;
  18. int mu[MAX],sig[MAX],ssig[MAX],pw[MAX],spw[MAX],dpw[MAX],dspw[MAX],dsig[MAX];
  19. int f[MAX],s[MAX];
  20. void Sieve(int n)
  21. {
  22. mu[1]=1;dsig[1]=sig[1]=1;
  23. for(int i=2;i<=n;++i)
  24. {
  25. if(!zs[i])
  26. {
  27. pri[++tot]=i,mu[i]=MOD-1;
  28. sig[i]=i+1,pw[i]=i,spw[i]=i+1;
  29. dsig[i]=dspw[i]=(1+i+1ll*i*i)%MOD;dpw[i]=1ll*i*i%MOD;
  30. }
  31. for(int j=1;j<=tot&&i*pri[j]<=n;++j)
  32. {
  33. zs[i*pri[j]]=true;
  34. if(i%pri[j])
  35. {
  36. mu[i*pri[j]]=MOD-mu[i];
  37. sig[i*pri[j]]=1ll*sig[i]*sig[pri[j]]%MOD;
  38. pw[i*pri[j]]=pri[j],spw[i*pri[j]]=1+pri[j];
  39. dsig[i*pri[j]]=1ll*dsig[i]*dsig[pri[j]]%MOD;
  40. dpw[i*pri[j]]=dpw[pri[j]];
  41. dspw[i*pri[j]]=dspw[pri[j]];
  42. }
  43. else
  44. {
  45. mu[i*pri[j]]=0;
  46. sig[i*pri[j]]=1ll*sig[i]*fpow(spw[i],MOD-2)%MOD*(spw[i]+pw[i]*pri[j])%MOD;
  47. pw[i*pri[j]]=pw[i]*pri[j];
  48. spw[i*pri[j]]=(spw[i]+pw[i]*pri[j])%MOD;
  49. dspw[i*pri[j]]=(dspw[i]+1ll*dpw[i]*pri[j]%MOD+1ll*dpw[i]*pri[j]%MOD*pri[j]%MOD)%MOD;
  50. dsig[i*pri[j]]=1ll*dsig[i]*fpow(dspw[i],MOD-2)%MOD*dspw[i*pri[j]]%MOD;
  51. dpw[i*pri[j]]=1ll*dpw[i]*pri[j]%MOD*pri[j]%MOD;
  52. break;
  53. }
  54. }
  55. }
  56. for(int i=1;i<=n;++i)dsig[i]=1ll*dsig[i]%MOD*i%MOD;
  57. for(int i=1;i<=n;++i)ssig[i]=(ssig[i-1]+sig[i])%MOD;
  58. for(int i=1;i<=n;++i)
  59. {
  60. if(mu[i])
  61. for(int j=i;j<=n;j+=i)
  62. f[j]=(f[j]+1ll*mu[i]*i%MOD*sig[j/i]%MOD*ssig[j/i])%MOD;
  63. f[i]=1ll*f[i]*i%MOD;s[i]=(s[i-1]+2ll*f[i]+MOD-dsig[i])%MOD;
  64. }
  65. }
  66. int main()
  67. {
  68. Sieve(MAX-1);
  69. int T=read();
  70. for(int i=1;i<=T;++i)
  71. printf("Case #%d: %d\n",i,s[read()]);
  72. return 0;
  73. }

【51Nod1584】加权约数和(数论)的更多相关文章

  1. 51Nod1584 加权约数和

    这题其实就是反演一波就好了(那你还推了一下午+一晚上),不过第一次碰到\(O(n\log n)\)预处理分块和式的方法-- 不知为啥我跟唐教主的题解推的式子不太一样--(虽然本质上可能是相同的吧) 那 ...

  2. 51nod1584加权约数和

    题目大意: 求: \[ \sum_{i-1}^n\sum_{j=1}^nmax(i,j)\sigma(i*j) \] 题解 对于这个\(\max\),套路的把它转化成: \[ 2*\sum_{i=1} ...

  3. 51NOD 1584 加权约数和 [莫比乌斯反演 转化 Trick]

    1584 加权约数和 题意:求\(\sum_{i=1}^{N} \sum_{j=1}^{N} {\max(i,j)\cdot \sigma(i\cdot j)}\) 多组数据\(n \le 10^6, ...

  4. 51nod 1584 加权约数和 约数和函数小trick 莫比乌斯反演

    LINK:加权约数和 我曾经一度认为莫比乌斯反演都是板子题. 做过这道题我认输了 不是什么东西都是板子. 一个trick 设\(s(x)\)为x的约数和函数. 有 \(s(i\cdot j)=\sum ...

  5. 洛谷P1403 [AHOI2005] 约数研究 [数论分块]

    题目传送门 约数研究 题目描述 科学家们在Samuel星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机“Samuel II”的长时间运算成为了可能.由于在去年一年的辛苦工作取得了不错的成绩, ...

  6. BZOJ-1968 COMMON 约数研究 数论+奇怪的姿势

    1968: [Ahoi2005]COMMON 约数研究 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1513 Solved: 1154 [Submit] ...

  7. 51nod 约数和(数论)

    题目链接: 约数和 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 有三个下标从1到n的数组a.b.c. a数组初始全为0. b[i]=∑j|ia[j] c[i]=∑j|ib[j] ...

  8. 51nod“省选”模测第二场 B 异或约数和(数论分块)

    题意 题目链接 Sol 这题是来搞笑的吧.. 考虑一个数的贡献是\(O(\frac{N}{i})\) 直接数论分块. #include<bits/stdc++.h> #define Pai ...

  9. [51Nod 1584] 加权约数和

    Description 在整理以前的试题时,他发现了这样一道题目:"求 \(\sum\sigma(i)\),其中 \(1≤i≤N\),\(σ(i)\) 表示 \(i\) 的约数之和.&quo ...

随机推荐

  1. 22(7).模型融合---CatBoost

    一.Catboost简介 全称:Gradient Boosting(梯度提升) + Categorical Features(类别型特征) 作者:俄罗斯的搜索巨头Yandex 官方地址 论文链接 | ...

  2. 剑指Offer-39.把数组排成最小的数(C++/Java)

    题目: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 分析: 将数组 ...

  3. java调用py文件传参执行

    java执行的也是py文件主函数. 传参: String url="*********************"; String[] args1 = new String[] { ...

  4. 【一起刷LeetCode】在未排序的数组中找到第 k 个最大的元素

    题目描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 ...

  5. 损失函数--KL散度与交叉熵

    损失函数 在逻辑回归建立过程中,我们需要一个关于模型参数的可导函数,并且它能够以某种方式衡量模型的效果.这种函数称为损失函数(loss function). 损失函数越小,则模型的预测效果越优.所以我 ...

  6. mysql workbench 报错:Can't analyze file, please try to change encoding type...

    Mysql workbench 导入csv can't analyze file 原因: workbench 识别csv第一行作为column名,column名不能为中文,所以报错.解决方法:csv第 ...

  7. 使用VBA从工作表中读图片,以及给工作表中写文件

    因为工作的原因,需要用到VBA,碰到读图片和写图片: Sub Macro01() '从工作表中保存图片 Application.ScreenUpdating = False Dim pth, shp, ...

  8. ASP.NET 页面控制

    一.HTTPRequest对象封装客户端请求页面或提交表单时提供的信息 请求方法:get/post 参数名/值 Cookie 使用的语言二.Rquest对象常用方法与属性 属性: QueryStrin ...

  9. 工作笔记 之 Python应用技术

    python socket编程详细介绍 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket,建立网络通信连接至少要一对端口号(socket). Socket本质是 ...

  10. 分布式应用监控: SkyWalking 快速接入实践

    分布式应用,会存在各种问题.而要解决这些难题,除了要应用自己做一些监控埋点外,还应该有一些外围的系统进行主动探测,主动发现. APM工具就是干这活的,SkyWalking 是国人开源的一款优秀的APM ...