51nod1238 最小公倍数之和 V3

n<=1e10,求1<=i<=n,1<=j<=n,lcm(i,j)的和。

又是充满坎坷的简单题。。。

Wait a minute 先打个miu和phi的表,以及一个暴力,随时检查式子!

来吧!

$\sum_{i=1}^{n}\sum_{j=1}^{n}[i,j]$

$=\sum_{i=1}^{n}\sum_{j=1}^{n}ij(i,j)^{-1}$

$=\sum_{d=1}^{n}d^{-1}\sum_{i=1}^{n}\sum_{j=1}^{n}ij[(i,j)=d]$

停住!

这里是一个重要抉择,后面怎么变换直接决定了做出这题的难度以及代码复杂度!!!

一、直接反演

$=\sum_{d=1}^{n}d^{-1}\sum_{d|t,t\leqslant n}\mu (\frac{t}{d})t^2(\frac{(1+\left \lfloor \frac{n}{t} \right \rfloor)\left \lfloor \frac{n}{t} \right \rfloor}{2})^2$

$=\sum_{t=1}^{n}t^2(\frac{(1+\left \lfloor \frac{n}{t} \right \rfloor)\left \lfloor \frac{n}{t} \right \rfloor}{2})^2\sum_{d|t}d^{-1}\mu(\frac{t}{d})$

闪一句:两个t丢后面。

$=\sum_{t=1}^{n}t^2(\frac{(1+\left \lfloor \frac{n}{t} \right \rfloor)\left \lfloor \frac{n}{t} \right \rfloor}{2})^2(t\sum_{d|t}d^{-1}\mu(\frac{t}{d}))$

需要求后面那堆的前缀和。转移战线:

$\sum_{t=1}^{n}t\sum_{d|t}d\mu(d)$

$=\sum_{t=1}^{n}\sum_{d|t}td\mu(d)$

$=\sum_{k=1}^{n}\sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}kd^2\mu(d)$

$=\sum_{d=1}^{n}d^2\mu(d)\sum_{k=1}^{\left \lfloor \frac{n}{d} \right \rfloor}k$

$=\sum_{d=1}^{n}(\frac{(1+\left \lfloor \frac{n}{d} \right \rfloor)\left \lfloor \frac{n}{d} \right \rfloor}{2})d^2\mu(d)$

好的!只需要一个$d^2\mu(d)$的前缀和即可。配俩Id(x)=x给他卷积:

$\sum_{i=1}^{n}\sum_{d|i}d^2\mu(d)(\frac{i}{d})^2$

$=\sum_{k=1}^{n}k^2\sum_{d=1}^{\left \lfloor \frac{i}{k} \right \rfloor}d^2\mu(d)$

于是$\sum_{i=1}^{n}i^2\mu(i)=1-\sum_{k=2}^{n}k^2\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}d^2\mu(d)$

套了若干个,还是$n^{\frac{2}{3}}$。但这代码量就。。

二、反演个鬼

$\sum_{d=1}^{n}d^{-1}\sum_{i=1}^{n}\sum_{j=1}^{n}ij[(i,j)=d]$

$=\sum_{d=1}^{n}d\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{n}{d} \right \rfloor}ij[(i,j)=1]$

$=\sum_{d=1}^{n}d((2\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}i\sum_{j=1}^{i}j[(i,j)=1])-1)$

$=\sum_{d=1}^{n}d((2\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}i\frac{i\varphi(i)+[i=1]}{2})-1)$

$=\sum_{d=1}^{n}d((\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}i^2\varphi(i)+[i=1])-1)$

$=\sum_{d=1}^{n}d\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}i^2\varphi(i)$

接着就是$i^2\varphi(i)$的前缀和啦!一样丢俩Id(x)=x给他卷积:

$\sum_{i=1}^{n}\sum_{d|i}d^2\varphi(d)(\frac{i}{d})^2$

$=\sum_{k=1}^{n}k^2\sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}d^2\varphi(d)$

得$\sum_{i=1}^{n}i^2\varphi(i)=(\frac{n(n+1)}{2})^2-\sum_{k=2}^{n}k^2\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}i^2\varphi(i)$

大功告成。

首先从正确性来说的话,以后一定要先打好表和暴力再来推,推两句检查一次。因为一半有推的人都可以推到类似nln(n)的复杂度,就算最后推不出正解,较多的暴力还是可以拿到的。

然后多尝试把不同的东西提出来,不要怕失败。

至于说这题两种不同的推法得到了两种时间相同但编码复杂度差别较大的方法,我认为是在学数论初期是难免的。多总结多锻炼也许就能少走弯路。

 1 #include<string.h>
 2 #include<stdlib.h>
 3 #include<stdio.h>
 4 #include<math.h>
 5 //#include<assert.h>
 6 #include<algorithm>
 7 //#include<iostream>
 8 //#include<bitset>
 9 using namespace std;
10
11 #define LL long long
12 LL n,m;
13 #define maxn 5000011
14 const int mod=1e9+7;
15 int phi[maxn],sumphi[maxn],prime[maxn],lp; bool notprime[maxn];
16
17 void pre(int n)
18 {
19     phi[1]=1; sumphi[1]=1;
20     for (int i=2;i<=n;i++)
21     {
22         if (!notprime[i]) {prime[++lp]=i; phi[i]=i-1;}
23         sumphi[i]=sumphi[i-1]+1ll*i*i%mod*phi[i]%mod;
24         sumphi[i]-=sumphi[i]>=mod?mod:0;
25         for (int tmp,j=1;j<=lp && 1ll*prime[j]*i<=n;j++)
26         {
27             notprime[tmp=prime[j]*i]=1;
28             if (i%prime[j]) phi[tmp]=phi[i]*(prime[j]-1);
29             else {phi[tmp]=phi[i]*prime[j]; break;}
30         }
31     }
32 }
33
34 struct Edge{LL to; int v,next;};
35 #define maxh 1000007
36 struct Hash
37 {
38     int first[maxh],le; Edge edge[maxn];
39     Hash() {le=2;}
40     void insert(LL y,int v) {int x=y%maxh; Edge &e=edge[le]; e.to=y; e.v=v; e.next=first[x]; first[x]=le++;}
41     int find(LL y) {int x=y%maxh; for (int i=first[x];i;i=edge[i].next) if (edge[i].to==y) return edge[i].v; return -1;}
42 }h;
43
44 int two=(mod+1)/2,six=(mod+1)/6;
45 int calc(LL n)
46 {
47     if (n<=m) return sumphi[n];
48     int tmp=h.find(n); if (tmp!=-1) return tmp;
49     int ans=(n%mod)%mod*((n+1)%mod)%mod*(n%mod)%mod*((n+1)%mod)%mod*two%mod*two%mod;
50     for (LL i=2,last;i<=n;i=last+1)
51     {
52         last=n/(n/i);
53         ans-=((last%mod)%mod*((last+1)%mod)%mod*((last+last+1)%mod)%mod*six%mod
54         -((i-1)%mod)%mod*(i%mod)%mod*((i+i-1)%mod)%mod*six%mod)*calc(n/i)%mod;
55         ans+=ans<0?mod:0; ans-=ans>=mod?mod:0;
56     }
57     h.insert(n,ans);
58     return ans;
59 }
60
61 int main()
62 {
63     scanf("%lld",&n);
64     m=pow(n,2.0/3); pre(m);
65     int ans=0;
66     for (LL i=1,last;i<=n;i=last+1)
67     {
68         last=n/(n/i);
69         ans+=((last-i+1)%mod)*((last+i)%mod)%mod*two%mod*calc(n/i)%mod;
70         ans-=ans>=mod?mod:0;
71     }
72     printf("%d\n",ans);
73     return 0;
74 }

原文地址:https://www.cnblogs.com/Blue233333/p/8320009.html

时间: 2024-11-09 04:51:03

51nod1238 最小公倍数之和 V3的相关文章

51nod1238 最小公倍数之和 V3 莫比乌斯函数 杜教筛

题意:求\(\sum_{i = 1}^{n}\sum_{j = 1}^{n}lcm(i, j)\). 题解:因为是用的莫比乌斯函数求的,所以推导比大部分题解多...而且我写式子一般都比较详细,所以可能看上去很多式子,实际上是因为每一步都写了,几乎没有跳过的.所以应该都可以看懂的. 末尾的\(e\)函数是指的\(e[1] = 1\),\(e[x] = 0(x != 1)\)这样一个函数 \[\sum_{i = 1}^{n}\sum_{j = 1}^{n}lcm(i, j)\] \[\sum_{i

51nod1238. 最小公倍数之和 V3(莫比乌斯反演)

题目链接 https://www.51nod.com/Challenge/Problem.html#!#problemId=1238 题解 本来想做个杜教筛板子题结果用另一种方法过了...... 所谓的"另一种方法"用到的技巧还是挺不错的,因此这里简单介绍一下. 首先还是基本的推式子: \[\begin{aligned}\sum_{i = 1}^n \sum_{j = 1}^n {\rm lcm}(i, j) &= \sum_{i = 1}^n \sum_{j = 1}^n \

[51nod1238] 最小公倍数之和 V3(杜教筛)

题面 传送门 题解 懒了--这里写得挺好的-- //minamoto #include<bits/stdc++.h> #define R register #define ll long long #define IT map<ll,int>::iterator #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i) #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i) #define go(

51 NOD 1238 最小公倍数之和 V3

原题链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1238 最近被51NOD的数论题各种刷……(NOI快到了我在干什么啊! 然后发现这题在网上找不到题解……那么既然A了就来骗一波访问量吧…… (然而并不会用什么公式编辑器,凑合着看吧…… Σ(1<=i<=n) Σ(1<=j<=n) i*j/gcd(i,j) =Σ(1<=d<=n) d * Σ(1<=i<=[n/d]) Σ(1&

【51nod】1238 最小公倍数之和 V3

[题意]给定n,求Σi=1~nΣj=1~n lcm(i,j),n<=10^10. [算法]杜教筛 [题解] $ans=\sum_{i=1}^{n}\sum_{j=1}^{i}lcm(i,j)$ 令$g(n)=\sum_{i=1}\frac{n*i}{(n,i)}$,则要求g(n)的前缀和. $g(n)=n\sum_{d|n}\sum_{i=1}^{n}\frac{i}{d}[(n,i)=d]$ $g(n)=n\sum_{d|n}\sum_{i=1}^{n/d}i[(n/d,i)=1]$ $g(n

51Nod 最大公约数之和V1,V2,V3;最小公倍数之和V1,V2,V3

1040 最大公约数之和 给出一个n,求1-n这n个数,同n的最大公约数的和.比如:n = 6 1,2,3,4,5,6 同6的最大公约数分别为1,2,3,2,1,6,加在一起 = 15 输入 1个数N(N <= 10^9) 输出 公约数之和 输入样例 6 输出样例 15 题解 \[ \sum_{i=1}^n\gcd(i,n)=\sum_{d|n}d\varphi(n) \] 暴力搞就行了. 1188 最大公约数之和 V2 给出一个数N,输出小于等于N的所有数,两两之间的最大公约数之和. 相当于计

1363 最小公倍数之和

1363 最小公倍数之和 题目来源: SPOJ 基准时间限制:1.5 秒 空间限制:131072 KB 给出一个n,求1-n这n个数,同n的最小公倍数的和.例如:n = 6,1,2,3,4,5,6 同6的最小公倍数分别为6,6,6,12,30,6,加在一起 = 66. 由于结果很大,输出Mod 1000000007的结果. Input 第1行:一个数T,表示后面用作输入测试的数的数量.(1 <= T <= 50000) 第2 - T + 1行:T个数A[i](A[i] <= 10^9)

BNU 12846 LCM Extreme 最小公倍数之和(线性欧拉筛选+递推)

LCM Extreme Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 596464-bit integer IO format: %lld      Java class name: Main Find the result of the following code:unsigned long long allPairLcm(int n){ unsig

BZOJ 1363 最小公倍数之和

Description 求\(\sum_{i=1}^n[i,n],n\leqslant 10^9,T\leqslant 5\times 10^4\) Solution 数论+欧拉函数... 破题有毒... 推导和BZOJ 2226: [Spoj 5971] LCMSum一样... 但是需要枚举所有约数,同时统计一下\(\varphi\)... Code #include <bits/stdc++.h> using namespace std; typedef long long ll; con