【51nod】1238 最小公倍数之和 V3 杜教筛
【题意】给定n,求Σi=1~nΣj=1~n lcm(i,j),n<=10^10。
【算法】杜教筛
【题解】就因为写了这个非常规写法,我折腾了3天……
$$ans=\sum_{i=1}^{n}\sum_{j=1}^{n}lcm(i,j)$$
令
$$g(n)=n*\sum_{i=1}^{n}\frac{i}{(n,i)}$$
那么
$$ans(n)=2*g(n)-\sum_{i=1}^{n}i$$
枚举gcd,化简g(n)。
$$g(n)=n*\sum_{d|n}1/d\sum_{i=1}^{n}i*[(n,i)=d]$$
令i=i/d
$$g(n)=n*\sum_{d|n}1/d\sum_{i=1}^{n/d}id*[(n/d,i)=1]$$
$$g(n)=n*\sum_{d|n}\sum_{i=1}^{n/d}i*[(n/d,i)=1]$$
由于
$$\sum_{i=1}^{n}[(n,i)=1]*i=\frac{n*\varphi(n)+[n==1]}{2}$$
所以代入,得
$$g(n)=n*\sum_{d|n}\frac{d*\varphi(d)+[d==1]}{2}$$
这里需要注意取整的问题,当d>1时d*φ(d)一定是偶数,当d=1时d*φ(d)=1就必须结合[d==1],于是可以化简成下面的形式。
$$g(n)=\frac{1}{2}n(1+\sum_{d|n}d*\varphi(d))$$
$$g(n)=\frac{1}{2}(n+n*\sum_{d|n}d*\varphi(d))$$
将上式代入ans,得
$$ans=2*\sum_{i=1}^{n}\frac{1}{2}(i+i*\sum_{d|i}d*\varphi(d)))-\sum_{i=1}^{n}i$$
$$ans=\sum_{i=1}^{n}i*\sum_{d|i}d*\varphi(d)$$
令
$$f(n)=n*\sum_{d|n}d*\varphi(d)$$
那么
$$ans=F(n)=\sum_{i=1}^{n}f(n)$$
★呼,经过上面一系列的化简,我们终于来到了杜教筛——求f(n)的前缀和。
$$f(n)=n*\sum_{d|n}d*\varphi(d)$$
将f表示成狄利克雷卷积的形式,根据点积的卷积分配律(乱起的名字)。
$$f=id \cdot (1*(id \cdot \varphi))=id*(id^2 \cdot \varphi)$$
发现其中有id^2的形式,我们知道同阶幂函数卷积有奇效www。(实际上应该是相同完全积性函数卷积有奇效)
$$g=id^2$$
$$f*g=(id^2 \cdot \varphi)*id*id^2=[(id^2 \cdot \varphi)*id^2]*id$$
双重卷积非常麻烦,考虑先化简方括号内的卷积
$$([(id^2 \cdot \varphi)*id^2])(i)=\sum_{d|n}d^2*\varphi(d)*\frac{n^2}{d^2}=n^2\sum_{d|n}\varphi(d)=n^3$$
成功化简!我们可以把f*g表示出来了!
$$(f*g)(i)=\sum_{d|n}d^3*\frac{n}{d}=n*\sum_{d|n}d^2$$
jiry_2在她的博客中表示这个柿子的前缀和是非常好求的。
我:???
假设h=f*g,那么
$$H(i)=\sum_{i=1}^{n}i*\sum_{d|i}d^2=\sum_{i=1}^{n}i^2\sum_{d=1}^{n/i}d*i=\sum_{i=1}^{n}i^3*\frac{\frac{n}{i}*(\frac{n}{i}+1)}{2}$$
然后就可以进行分块取值优化了,注意G和H的求解复杂度为O(1)~O(√n)对杜教筛的总复杂度都没有影响。
最终杜教筛的形式是
$$F(n)=H(n)-\sum_{i=2}^{n}i^2*F(\frac{n}{i})$$
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
const int MOD=1e9+,preN=,v=(MOD+)/;
int N,f[preN+],phi[preN+],e[preN+],a[],prime[],tot;
int A(int n){return n%MOD*(n%MOD+)%MOD*v%MOD;}
int B(int n){return n%MOD*(n%MOD+)%MOD*(*n%MOD+)%MOD*((MOD+)/)%MOD;}
int K(int x){return x*x%MOD;}
int C(int n){return K(A(n));}
int query(int n){
int pos=,ans=;
for(int i=;i<=n;i=pos+){
pos=n/(n/i);
ans=(ans+(C(pos)-C(i-)+MOD)*A(n/i)%MOD)%MOD;
}
return ans;
}
int solve(int n){
if(n<=preN)return f[n];
if(~a[N/n])return a[N/n];
int ans=query(n);
int pos=;
for(int i=;i<=n;i=pos+){
pos=n/(n/i);
ans=(ans-(B(pos)-B(i-)+MOD)*solve(n/i)%MOD+MOD)%MOD;
}
return a[N/n]=ans;
}
#undef int
int main(){
#define int long long
scanf("%lld",&N);
phi[]=;f[]=;e[]=;
for(int i=;i<=preN;i++){
if(!e[i]){
phi[prime[++tot]=i]=i-;
e[i]=i;
f[i]=(i*phi[i]+)%MOD;
}
for(int j=;j<=tot&&i*prime[j]<=preN;j++){
int k=i*prime[j];
if(i%prime[j]==){
e[k]=e[i]*prime[j];
phi[k]=phi[i]*prime[j];
f[k]=(f[i]+f[i/e[i]]*phi[e[k]]%MOD*e[k]%MOD)%MOD;
break;
}
e[k]=prime[j];
phi[k]=phi[i]*(prime[j]-);
f[k]=f[i]*f[prime[j]]%MOD;
}
}
for(int i=;i<=preN;i++)f[i]=(f[i-]+f[i]*i%MOD)%MOD;
memset(a,-,sizeof(a));
printf("%lld",solve(N));
return ;
}
1.F(n)的预处理:在i%prime[j]时,f[i*prime[j]]=f[i]+f[i/e[i]]*φ(e[i]*prime[j])*(e[i]*prime[j]),其中e[i]是 i 的所有最小素因子乘积(p1^k1)。
2. 1~3次幂前缀和
$$\sum_{i=1}^{n}i=\frac{n(n+1)}{2}$$
$$\sum_{i=1}^{n}i^2=\frac{n(n+1)(2n+1)}{6}$$
$$\sum_{i=1}^{n}i^3=(\frac{n(n+1)}{2})^2$$
3.x的逆元是(MOD+1)/x,如果这是个整数。
4.全程long long的话,define比较好。而且输入的n是long long的话,n*n会爆long long。
【另一种写法】
$$ans=\sum_{i=1}^{n}\sum_{i=1}^{n}\frac{i*j}{(i,j)}$$
直接枚举gcd值
$$ans=\sum_{d=1}^{n}1/d\sum_{i=1}^{n/d}\sum_{i=1}^{n/d}d^2*i*j*[(i,j)=1]$$
$$ans=\sum_{d=1}^{n}d\sum_{i=1}^{n/d}\sum_{j=1}^{n/d}i*j*[(i,j)=1]$$
这里看到[(i,j)=1]很容易想到莫比乌斯反演,但是这个问题如果反演会变得相当复杂,应该留到后面用n*φ(n)/2化简。
从上式已经可以看出分块取值优化的形式了。
令
$$s(n)=\sum_{i=1}^{n}\sum_{j=1}^{n}i*j*[(i,j)=1]$$
那么
$$ans=\sum_{d=1}^{n}d*s(n/d)$$
为了将s(n)表示成前缀和的形式,将矩形转化为上三角。
$$s(n)=2*(\sum_{i=1}^{n}\sum_{j=1}^{i}i*j*[(i,j)=1])-1$$
$$s(n)=2*P(n)-1$$
$$p(n)=n*\sum_{i=1}^{n}i*[(n,i)=1]$$
然后就可以转化了
$$p(n)=n*\frac{n*\varphi(n)+[n==1]}{2}=\frac{1}{2}(n^2\varphi(n)+n)$$
令
$$f(n)=n^2\varphi(n)$$
那么s(n)可以表示为
$$s(n)=F(n)+\frac{n(n+1)}{2}-1$$
然后我们就可以用杜教筛求解f(n)的前缀和。
$$f=id^2 \cdot \varphi$$
$$g=id^2$$
$$f*g=id^3$$
因为分块和杜教筛都是求n/i,所以复杂度并列,最终O(n^2/3)。
【51nod】1238 最小公倍数之和 V3 杜教筛的更多相关文章
- 51NOD 1238 最小公倍数之和 V3 [杜教筛]
1238 最小公倍数之和 V3 三种做法!!! 见学习笔记,这里只贴代码 #include <iostream> #include <cstdio> #include < ...
- [51Nod 1238] 最小公倍数之和 (恶心杜教筛)
题目描述 求∑i=1N∑j=1Nlcm(i,j)\sum_{i=1}^N\sum_{j=1}^Nlcm(i,j)i=1∑Nj=1∑Nlcm(i,j) 2<=N<=10102<=N ...
- 51 Nod 1238 最小公倍数之和 V3 杜教筛
题目链接:http://www.51nod.com/Challenge/Problem.html#!#problemId=1238 题意:求$\sum_{i=1}^{n}\sum_{j=1}^{n}l ...
- [51Nod1238]最小公倍数之和 V3[杜教筛]
题意 给定 \(n\) ,求 \(\sum_{i=1}^n \sum_{j=1}^n lcm(i,j)\). \(n\leq 10^{10}\) 分析 推式子 \[\begin{aligned} an ...
- 51nod 1238 最小公倍数之和 V3
51nod 1238 最小公倍数之和 V3 求 \[ \sum_{i=1}^N\sum_{j=1}^N lcm(i,j) \] \(N\leq 10^{10}\) 先按照套路推一波反演的式子: \[ ...
- 51nod 1238 最小公倍数之和 V3 【欧拉函数+杜教筛】
首先题目中给出的代码打错了,少了个等于号,应该是 G=0; for(i=1;i<=N;i++) for(j=1;j<=N;j++) { G = (G + lcm(i,j)) % 10000 ...
- 51Nod 1238 - 最小公倍数之和 V3(毒瘤数学+杜教筛)
题目 戳这里 推导 ∑i=1n∑j=1nlcm(i,j)~~~\sum_{i=1}^{n}\sum_{j=1}^{n}lcm(i,j) ∑i=1n∑j=1nlcm(i,j) =∑i=1n∑j= ...
- 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 ...
- 51nod 237 最大公约数之和 V3 杜教筛
Code: #include <bits/stdc++.h> #include <tr1/unordered_map> #define setIO(s) freopen(s&q ...
随机推荐
- WebSphere应用服务器内存泄漏探测与诊断工具选择最佳实践
内存泄漏是比较常见的一种应用程序性能问题,一旦发生,则系统的可用内存和性能持续下降:最终将导致内存不足(OutOfMemory),系统彻底宕掉,不能响应任何请求,其危害相当严重.同时,Java堆(He ...
- emacs编译整个emacs.d目录
$emacs 在emacs查看里面,输入: C-u M-x byte-recompile-directory 然后输入 ~/.emacs.d 即可.
- Objective - C 之协议
一.创建方法: 二.实现过程: 1.遵循协议: @protocol NurseWorkingProtocol <NSObject> //<> 表示遵守协议,创建时就有(Nu ...
- log4j配置独立日志方法
不使用类,而是使用loggerName来创建日志: #json是用java代码创建logger时用name,而不是jsonlog,注意,不需要在rootLogger中再配置,否则其它无关信息也将输出到 ...
- layabox 3d 入手
最近受到打击了,3d效果远比2d效果好. 问题 laya3d 有正交相机没有? Laya.Sprite3D.load(XX.lh); 克隆Laya.Sprite3D.instantiate Lay ...
- 原子性、内存可见性和重排序——重新认识synchronized和volatile
一.原子性 原子性操作指相应的操作是单一不可分割的操作.例如,对int变量count执行count++d操作就不是原子性操作.因为count++实际上可以分解为3个操作:(1)读取变量count的当前 ...
- [SDOI2011]黑白棋 kth - nim游戏
题面 题面 题解 观察题目,我们可以发现,这个游戏其实就是不断再把对方挤到一边去,也就是黑子不断往左走,白子不断往右走. 因此可以发现,如果将黑白子按顺序两两配对,那么它们中间的距离会不断缩小,且每次 ...
- 洛谷 P2604 [ZJOI2010]网络扩容 解题报告
P2604 [ZJOI2010]网络扩容 题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. ...
- 服务器启动脚本 /etc/rc.local
#启动php-frm/home/www/php/sbin/php-fpm #启动搜索引擎/home/www/se/bin/xs-ctl.sh start #启动lighttpd/home/www/li ...
- Communications link failure;;The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure::The ...