https://www.51nod.com/Challenge/Problem.html#!#problemId=1188

求\(\sum\limits_{i=1}^{n-1}\sum\limits_{j=i+1}^{n}gcd(i,j)\)

首先交换求和\(\sum\limits_{j=2}^{n}\sum\limits_{i=1}^{j-1}gcd(i,j)=\sum\limits_{j=2}^{n}\sum\limits_{i=1}^{j}gcd(i,j)-j\)


像之前那样用莫比乌斯反演搞出

\(\sum\limits_{g=1}^{n}g\sum\limits_{i=1}^{\lfloor\frac{n}{g}\rfloor}{\varphi(i)}, (\varphi(1)=0)\)

或者

\(\sum\limits_{g=1}^{n}g\sum\limits_{i=1}^{\lfloor\frac{n}{g}\rfloor}{\mu(i)}*{\lfloor\frac{n}{i*g}\rfloor}^2\)

都是T了,说明单次回答的复杂度非常感人,原因是因为跟n有关就逃不了分块。

所以分块的复杂度还是太高了。

然后惊人的事情发生了。

这道题和前面的不一样的地方在于,他的n其实没有前面的大,只是多!

分块的意义在于加快单次回答的速度,所以才把g提了出来分块,现在不太合适。


正解,先求解:

\(\sum\limits_{i=1}^{n}gcd(i,n)\)

这个东西可以枚举g:

\(\sum\limits_{g=1}^{n}g\sum\limits_{i=1}^{n}[gcd(i,n)==g]\)

\(\sum\limits_{g=1}^{n}g\sum\limits_{i=1}^{\lfloor\frac{n}{g}\rfloor}[gcd(i,\lfloor\frac{n}{g}\rfloor)==1]\)

\(\sum\limits_{g=1}^{n}g\varphi(\lfloor\frac{n}{g}\rfloor)\)

这个有什么不对呢?其实没什么不对,就是不好。因为gcd必定是整除n的,所以可以:

\(\sum\limits_{g|n}g\varphi(\frac{n}{g})\)

这明显就是一个积性函数,记为 \(p(n)\) ,处理好就可以了。原式:

\(\sum\limits_{j=2}^{n}p(j)-j\)

这个式子 \(p(n)\) 用埃筛已经足够了,因为是5e6的数据量,1400ms/2000ms跑过去了。但是我在想会不会有线性的筛法。

2019/6/7早上试了很多种之后,发现还是直接利用积性函数的结论最简单,对于每个合数记录他的最小质因子及其幂次,然后一除就得到两个互质的因数。

问题在于纯p的幂次一除就变成没有了。也就是别人的博客说的 \(p^k\) 要特殊处理,想到上面这个式子是一个狄利克雷卷积,对于纯p的幂次只要从他的低1次转移过来就可以了。

最后套上快读快写狗掉榜首!需要注意的是我准备的线性筛模板里多用了0.25倍空间,其实真的可以充分利用的。比如这个的话pk肯定不是0,那么就用pk来做判断就可以了。

所以说的确是空间换时间,多了0.5倍的空间省去一个logn倍。200ms/2000ms稳得一笔。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. inline int read() {
  5. int x=0;
  6. char c=getchar();
  7. while(c<'0'||c>'9')
  8. c=getchar();
  9. do {
  10. x=(x<<3)+(x<<1)+c-'0';
  11. c=getchar();
  12. } while(c>='0'&&c<='9');
  13. return x;
  14. }
  15. inline void write(ll x) {
  16. //printf("%lld\n",x);
  17. if(x>9) {
  18. write(x/10);
  19. }
  20. putchar(x%10+'0');
  21. return;
  22. }
  23. const int MAXN=5e6;
  24. int pri[MAXN+1];
  25. int &pritop=pri[0];
  26. ll ans[MAXN+1];
  27. int pk[MAXN+1];//pk(n)=pk的最小因子p的次方
  28. void sieve(int n=MAXN) {
  29. ans[1]=1;
  30. pk[1]=1;
  31. for(int i=2; i<=n; i++) {
  32. if(!pk[i]) {
  33. pri[++pritop]=i;
  34. ans[i]=i+i-1;
  35. pk[i]=i;
  36. }
  37. for(int j=1; j<=pritop&&i*pri[j]<=n; j++) {
  38. int t=i*pri[j];
  39. if(i%pri[j]) {
  40. pk[t]=pk[pri[j]];
  41. ans[t]=ans[i]*ans[pri[j]];
  42. } else {
  43. pk[t]=pk[i]*pri[j];
  44. if(pk[t]==t) {
  45. //纯p的幂次,没有其他因子,这样算不会漏因子
  46. //t-t/pri[j]就是phi[t]
  47. ans[t]=(t-t/pri[j])+ans[i]*pri[j];
  48. } else {
  49. //积性函数
  50. ans[t]=ans[pk[t]]*(ans[t/pk[t]]);
  51. }
  52. break;
  53. }
  54. }
  55. }
  56. for(int i=1; i<=n; i++)
  57. ans[i]+=ans[i-1]-i;
  58. }
  59. inline void solve() {
  60. sieve();
  61. int T=read();
  62. while(T--) {
  63. int n=read();
  64. write(ans[n]);
  65. putchar('\n');
  66. }
  67. }
  68. int main() {
  69. #ifdef Yinku
  70. freopen("Yinku.in","r",stdin);
  71. #endif // Yinku
  72. solve();
  73. return 0;
  74. }

其他尝试?

现在把g放回去。

\(\sum\limits_{g=1}^{n}\sum\limits_{i=1}^{\lfloor\frac{n}{g}\rfloor}g*{\varphi(i)}, (\varphi(1)=0)\)

这个不就是相当于把每个 \(i*g \leq n\) 的加起来吗?所以当然可以交换求和顺序!

\(\sum\limits_{i=1}^{n}\sum\limits_{g=1}^{\lfloor\frac{n}{i}\rfloor}g*{\varphi(i)}, (\varphi(1)=0)\)

前面是一个干净的前缀和,后面那个式子是nlogn的!

也就是预处理:

\(ans(n)=\sum\limits_{g=1}^{\lfloor\frac{n}{i}\rfloor}g*{\varphi(i)}, (\varphi(1)=0)\)

51nod - 1188 - 最大公约数之和 V2 - 数论的更多相关文章

  1. 51nod 1188 最大公约数之和 V2

    第二个\( O(T\sqrt(n)) \)复杂度T了..T了..T了...天地良心,这能差多少?! 于是跑去现算(. \[ \sum_{i=1}^{n-1}\sum_{j=i+1}^{n}gcd(i, ...

  2. 51 nod 1188 最大公约数之和 V2

    1188 最大公约数之和 V2 题目来源: UVA 基准时间限制:2 秒 空间限制:262144 KB 分值: 160 难度:6级算法题   给出一个数N,输出小于等于N的所有数,两两之间的最大公约数 ...

  3. 1188 最大公约数之和 V2

    1188 最大公约数之和 V2 题目来源: UVA 基准时间限制:2 秒 空间限制:262144 KB  给出一个数N,输出小于等于N的所有数,两两之间的最大公约数之和.       相当于计算这段程 ...

  4. 51nod 1040:最大公约数之和(数论)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1040 给出一个n,求1-n这n个数,同n的最大公约数的和. ...

  5. 51nod1188 最大公约数之和 V2

    考虑每一个数对于答案的贡献.复杂度是O(nlogn)的.因为1/1+1/2+1/3+1/4......是logn级别的 //gcd(i,j)=2=>gcd(i/2,j/2)=1=>phi( ...

  6. 51nod 1040 最大公约数之和(欧拉函数)

    1040 最大公约数之和 题目来源: rihkddd 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   给出一个n,求1-n这n个数,同n的最大公约数的和.比如: ...

  7. 51nod 1237 最大公约数之和 V3(杜教筛)

    [题目链接] https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1237 [题目大意] 求[1,n][1,n]最大公约数之和 ...

  8. 51nod 1040 最大公约数之和 欧拉函数

    1040 最大公约数之和 题目连接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1040 Description 给 ...

  9. 51NOD 1237 最大公约数之和 V3 [杜教筛]

    1237 最大公约数之和 V3 题意:求\(\sum_{i=1}^n\sum_{j=1}^n(i,j)\) 令\(A(n)=\sum_{i=1}^n(n,i) = \sum_{d\mid n}d \c ...

随机推荐

  1. 用python编写的无线AP扫描器

    代码如下: #coding=utf-8 import os import sys import subprocess from scapy.all import * RSN = 48 #管理帧信息元素 ...

  2. 去除input框的值

    onfocus="this.value=' ';" <input type="text" name="buynum" id=" ...

  3. Redis 3.2.4编译安装

    1. 下载安装包 wget url tar zxvf redis-3.2.4.tar.gz 2. 编译安装 cd redis-3.2.4/src/ sudo make && make ...

  4. Linux命令之ln软链接

    用途:链接文件 默认情况下,ln命令产生硬链接. 最常用的参数是-s(建立符号连接Symbolic Link,也叫软连接),具体用法是: ln-s 源文件 目标文件 当我们需要在不同的目录用到相同的文 ...

  5. MVC入门——列表页

    创建控制器UserInfoController using System; using System.Collections.Generic; using System.Linq; using Sys ...

  6. PAT 天梯赛 L1-050. 倒数第N个字符串 【字符串】

    题目链接 https://www.patest.cn/contests/gplt/L1-050 思路 因为是求倒数 我们不如直接 倒过来看 令 zzz 为第一个字符串 我们可以理解为 十进制 转换为 ...

  7. ubuntu12.04离线安装libjpeg62-dev

    0:如果的电脑能连接上网络,用apt-get install安装最爽,我的情况是:公司电脑用的内网,访问不了外网,而且不让访问外网,安装软件只能用u盘拷进去再安装,所以我用如下方法 1:下载安装包,地 ...

  8. [CPP - STL] functor刨根问底儿

    作为STL六大组件之一,在STL源代码及其应用中,很多地方使用了仿函数(functor),尤其在关联型容器(如set.map)以及algorithm(如find_if.count_if等)中.虽然已经 ...

  9. Double.valueOf()与Double.parseDouble()两者的区别

    写代码用到这两个方法,不知道有什么区别,看一下源码: Double.parseDouble(String str) public static double parseDouble(String s) ...

  10. 测试工程师面试题之:给你印象最深的Bug

    有人看到别人在侵淫面试技巧,什么<程序员面试宝典>,或者<面试测试工程师须知>等等,就会嗤之以鼻.他会觉得这不是“投机取巧”吗,最重要的还是踏实提高自己的能力. 非常同意这种看 ...