【学术篇】51nod 1238 最小公倍数之和

这是一道杜教筛的入(du)门(liu)题目...


题目大意


\[
\sum_{i=1}^n\sum_{j=1}^nlcm(i,j)
\]

一看就是辣鸡反演一类的题目, 那就化式子呗..
\[
\sum_{i=1}^n\sum_{j=1}^nlcm(i,j) \=\sum_{i=1}^n\sum_{j=1}^n\frac{ij}{gcd(i,j)} \=\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^n\frac{ij}k[gcd(i,j)=k] \=\sum_{k=1}^n\sum_{i=1}^{\left\lfloor\frac nk\right\rfloor}\sum_{j=1}^{\left\lfloor\frac nk\right\rfloor}ijk[gcd(i,j)=1] \=\sum_{k=1}^nk\sum_{i=1}^{\left\lfloor\frac nk\right\rfloor}i\sum_{j=1}^{\left\lfloor\frac nk\right\rfloor}j[gcd(i,j)=1] \=\sum_{k=1}^nk\sum_{i=1}^{\left\lfloor\frac nk\right\rfloor}i\sum_{j=1}^{\left\lfloor\frac nk\right\rfloor}j\sum_{d=1}^{\left\lfloor\frac nk\right\rfloor}[d|i][d|j]\mu(d) \=\sum_{k=1}^nk\sum_{d=1}^{\left\lfloor\frac nk\right\rfloor}\mu(d) \sum_{i=1}^{\left\lfloor\frac nk\right\rfloor}[d|i]i \sum_{j=1}^{\left\lfloor\frac nk\right\rfloor}[d|j]j \设i=dq,j=dq, \原式=\sum_{k=1}^nk\sum_{d=1}^{\left\lfloor\frac nk\right\rfloor}\mu(d) \sum_{p=1}^{\left\lfloor\frac nk\right\rfloor}dp \sum_{q=1}^{\left\lfloor\frac nk\right\rfloor}dq \=\sum_{k=1}^nk\sum_{d=1}^{\left\lfloor\frac nk\right\rfloor}\mu(d)*d^2\sum_{p=1}^{\left\lfloor\frac nk\right\rfloor}p \sum_{q=1}^{\left\lfloor\frac nk\right\rfloor}q \\because\sum_{i=1}^ni=\frac{n(n+1)}2, \\therefore原式=\sum_{k=1}^nk\sum_{d=1}^{\left\lfloor\frac nk\right\rfloor}\mu(d)*d^2(\frac{{\left\lfloor\frac nk\right\rfloor}({\left\lfloor\frac nk\right\rfloor}+1)}{2})^2 \设t=kd, \原式=\sum_{t=1}^n(\frac{{\left\lfloor\frac nt\right\rfloor}({\left\lfloor\frac nt\right\rfloor}+1)}{2})^2\sum_{d|t}\mu(d)*td \设g(x)=\sum_{d|x}\mu(x)*xd, \则原式=\sum_{t=1}^n(\frac{{\left\lfloor\frac nt\right\rfloor}({\left\lfloor\frac nt\right\rfloor}+1)}{2})^2g(t)
\]
然后前面这一堆我们可以分块\(O(1)\)搞出来, 所以问题的关键就变成了求\(g(x)\)的前缀和.
因为题目中\(n\leq10^{10}\), 所以这里要用\(O(n^\frac23)\)的杜教筛.
但是杜教筛的框架我们是知道的,
\[
设要求前缀和的函数为f(x), 其前缀和为s_f(x) \设有好求前缀和的积性函数g(x)和h(x), 使得(f*g)(x)=h(x), \设h(x)的前缀和为s_h(x), 则有 \s_f(x)=\frac{s_h(x)-\sum_{d=2}^ns_f({\left\lfloor\frac nd\right\rfloor})g(d)}{g(1)}
\]
所以我们的任务又变成了找到合适的\(g(x)\)和\(h(x)\).
在某篇歪果仁的blog上, 他说:

With a little luck, we can notice that Id(l)?=?g?*?Id2(l),

  • 注: \(id(x)=x\)(以下称为\(n\))\(id2(x)=x^2\)(以下称为\(n_2\))

But 这运气也太好了点吧? 我怎么就找不到这种函数呢?!
不过我们还是要考虑一下的... (这波化式子的时候注意乘号\(\cdot\)和卷积号\(*\))
\[
g(x)=\sum_{d|x}\mu(d)xd \=\sum_{d|x}x^2\mu(d)\frac dx \=x^2\sum_{d|x}\mu(d)\frac dx \=x^2\cdot(\mu*n) \(g*n_2)(x) \=(x^2\cdot\mu*n)*n_2 \cdots ① \积性函数有一个性质, 如果两边的乘积都含有某一项的时候, 可以把这一项提出来. \所以我们可以把x^2都提出来, (证明可以用定义式推咯~) \①=(x^2\cdot\mu*n_2)*n \=x^2\cdot(\mu*1)*n \=x^2\cdot\epsilon*n =n
\]
所以我们就证明出来了\((g*n_2)(x)=n(x)\)
这样就可以直接杜教筛了= =
然后就是注意细节了OvO
比如非常坑人的\(10^{10}*(1e9+7)\)会爆long long!!
所以要开unsigned...
就这样吧= =
代码:

#include <map>
#include <cstring>
#include <iostream>
using namespace std;
typedef unsigned long long LL;
#define ri register int
#define rll register unsigned long long
const int p=1e9+7;
int qpow(int a,int b,int s=1){
    for(;b;b>>=1,a=1LL*a*a%p)
        if(b&1) s=1LL*s*a%p;
    return s;
}
const int inv2=qpow(2,p-2),inv4=qpow(4,p-2),inv6=qpow(6,p-2);
const int N=4800000,_N=N+10;
const int SQ=233333;
LL n;
map<LL,int> mp;
map<LL,int>::iterator it;
int g[_N],pr[N/2],tot;
bool notp[_N];
void shai(){
    g[1]=1; ri i,j; rll k;
    for(i=2;i<=N;++i){
        if(!notp[i])
            pr[++tot]=i,g[i]=(-1LL*i*(i-1)%p+p)%p;
        for(j=1;j<=tot&&(k=1LL*i*pr[j])<=N;++j){
            notp[k]=1;
            if(i%pr[j]==0){g[k]=1LL*g[i]*pr[j]%p;break;}
            g[k]=1LL*g[i]*g[pr[j]]%p;
        }
    }
    for(i=2;i<=N;++i) g[i]=(g[i]+g[i-1])%p;
}
inline int calcsqr(LL x){x%=p;return x*(x+1)%p*(2*x+1)%p*inv6%p;}
inline int calcsum(LL x){x%=p;return x*x%p*(x+1)%p*(x+1)%p*inv4%p;}
int calc(LL x){
    if(x<=N) return g[x];
    it=mp.find(x);
    if(it!=mp.end()) return it->second;
    int ans=1LL*x%p*(x+1)%p*inv2%p;
    LL last=0;
    for(rll i=2;i<=x;i=last+1){
        last=x/(x/i);
        ans=(ans-1LL*calc(x/i)*(calcsqr(last)-calcsqr(i-1)+p)%p+p)%p;
    }
    return mp[x]=(ans%p+p)%p;
}
int main(){
    shai();cin>>n;
    LL last=0; int ans=0;
    for(rll i=1;i<=n;i=last+1){
        last=n/(n/i);
        ans=(ans+1LL*calcsum(n/i)*(calc(last)-calc(i-1)+p)%p)%p;
    }
    cout<<ans;
}

这破题我连推带写加总结写了整整一天!!!
窝还是太弱了..

原文地址:https://www.cnblogs.com/enzymii/p/8505328.html

时间: 2024-10-20 16:19:43

【学术篇】51nod 1238 最小公倍数之和的相关文章

【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

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 - 1363 - 最小公倍数之和 - 数论

https://www.51nod.com/Challenge/Problem.html#!#problemId=1363 求\(\sum\limits_{i=1}^{n}lcm(i,n)\) 先换成gcd: \(\sum\limits_{i=1}^{n}\frac{i*n}{gcd(i,n)}\) 显而易见,枚举g: $ n * \sum\limits_{g|n} \frac{1}{g} \sum\limits_{i=1}^{n} i*[gcd(i,n)==g] $ 提g,没有下整符号: $

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)

[2016-05-09][51nod][1012 最小公倍数LCM]

时间:2016-05-09 18:53:56 星期一 题目编号:[2016-05-09][51nod][1012 最小公倍数LCM] 题目大意:求a和b的最小公倍数 #include<cstdio> using namespace std; typedef long long ll; ll gcd(ll a,ll b){ return b == 0 ? a : gcd(b ,a%b); } ll lcm(ll a,ll b){ return a / gcd(a,b) * b; } int ma

51nod 1363 最小公倍数的和 欧拉函数+二进制枚举

1363 最小公倍数之和 题目来源: SPOJ 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 给出一个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] <

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

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 \