[bzoj 4176] Lucas的数论 (杜教筛 + 莫比乌斯反演)
题面
设d(x)d(x)d(x)为xxx的约数个数,给定NNN,求 ∑i=1N∑j=1Nd(ij)\sum^{N}_{i=1}\sum^{N}_{j=1} d(ij)i=1∑Nj=1∑Nd(ij)
N<=109N<=10^9N<=109
题目分析
有这样一个结论
d(ij)=∑x∣i∑y∣j[(x,y)==1]d(ij)=\sum_{x|i}\sum_{y|j}[(x,y)==1]d(ij)=x∣i∑y∣j∑[(x,y)==1]这道题就是下面这道题的数据增强版,那么这个结论的证明就不再赘述,请自行查看下面的(蒟蒻)博客 传送门:[SDOI2015][bzoj 3994][Luogu P3327] 约数个数和
Ans=∑k=1Nμ(k)(∑x=1⌊Nk⌋⌊Nkx⌋)2\large Ans=\sum_{k=1}^N\mu(k)\left(\sum_{x=1}^{⌊\frac{N}{k}⌋}⌊\frac{N}{kx}⌋\right)^2Ans=k=1∑Nμ(k)⎝⎜⎛x=1∑⌊kN⌋⌊kxN⌋⎠⎟⎞2
由于数据范围的增强,我们不能预处理完整个10910^9109,于是就外层整除分块优化
- 内层杜教筛来算μ\muμ的前缀和,时间复杂度为Θ(N23)\Theta (N^{\frac 23})Θ(N32)
- 后面平方的底数实际上等于[1,⌊Nk⌋]\left[1,⌊\frac{N}{k}⌋\right][1,⌊kN⌋]的约数个数和的前缀和,可以直接Θ(⌊Nk⌋)\Theta(\sqrt {⌊\frac{N}{k}⌋})Θ(⌊kN⌋)算,预处理出前N23N^{\frac23}N32的约数个数和的前缀和后,总时间复杂度就如杜教筛一样为Θ(N23)\Theta(N^\frac 23)Θ(N32)
总时间复杂度为Θ(N23)\Theta (N^{\frac 23})Θ(N32)
AC code
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 1;
const int mod = 1e9 + 7;
int Cnt, Prime[N], mu[N], d[N], a[N]; //a[i]存的是i的最小质因数的次数+1
bool IsnotPrime[N];
void init()
{
mu[1] = d[1] = a[1] = 1;
for(int i = 2; i < N; ++i)
{
if(!IsnotPrime[i])
Prime[++Cnt] = i, mu[i] = -1, a[i] = d[i] = 2;
for(int j = 1; j <= Cnt && i * Prime[j] < N; ++j)
{
IsnotPrime[i * Prime[j]] = 1;
if(i % Prime[j] == 0)
{
mu[i * Prime[j]] = 0;
d[i * Prime[j]] = d[i] / a[i] * (a[i * Prime[j]] = a[i] + 1);
break;
}
mu[i * Prime[j]] = -mu[i];
d[i * Prime[j]] = d[i] * (a[i * Prime[j]] = 2);
}
}
for(int i = 1; i < N; ++i)
(d[i] += d[i-1]) %= mod, (mu[i] += mu[i-1]) %= mod;
}
inline int sum_d(int n) //约数个数和的前缀和,也就是后面个平方的底数
{
if(n < N) return d[n];
int ret = 0;
for(int i = 1, j; i <= n; i=j+1)
{
j = n/(n/i);
ret = (ret + (LL)(n/i) * (j-i+1) % mod) % mod;
}
return ret;
}
map<int, int>s;
inline int sum_mu(int n)
{
if(n < N) return mu[n];
if(s.count(n)) return s[n];
int ret = 1;
for(int i = 2, j; i <= n; i=j+1)
{
j = n/(n/i);
ret = (ret - (LL)sum_mu(n/i)*(j-i+1)%mod) % mod;
}
return s[n]=ret;
}
int solve(int n)
{
int ret = 0, last = 0, tmp, tmp2;
for(int i = 1, j; i <= n; i=j+1)
{
j = n/(n/i);
tmp = sum_mu(j), tmp2 = sum_d(n/i), tmp2 = (LL)tmp2 * tmp2 % mod;
//tmp2存后面那个平方的值
ret = (ret + (LL)((tmp-last) % mod) * tmp2 % mod) % mod;
last = tmp;//这利用了一个小优化,本来是sum_mu(j)-sum_mu(i-1),
//我们把sum_mu(i-1)的值存下来,就少计算一次,last存上一次答案
//然而我后来看发现这优化并没有什么卵用,本来就记忆化了...
}
return ret;
}
int main ()
{
init(); int n;
scanf("%d", &n);
printf("%d\n", (solve(n)+mod)%mod);
}
.
.
.
少有的一A
二刷:bzoj rank 7
CODE
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1000005;
const int mod = 1e9 + 7;
int prime[MAXN/10], cnt, mu[MAXN], d[MAXN], a[MAXN];
bool vis[MAXN];
inline void Pre_Work(int n) {
mu[1] = d[1] = a[1] = 1;
for(int i = 2; i <= n; ++i) {
if(!vis[i])
prime[++cnt] = i, mu[i] = -1, d[i] = a[i] = 2;
for(int j = 1; j <= cnt && i*prime[j] <= n; ++j) {
vis[i*prime[j]] = 1;
if(i % prime[j] == 0) {
mu[i*prime[j]] = 0;
d[i*prime[j]] = d[i] / a[i] * (a[i*prime[j]] = a[i]+1);
break;
}
mu[i*prime[j]] = -mu[i];
d[i*prime[j]] = d[i] * (a[i*prime[j]] = 2);
}
}
for(int i = 2; i <= n; ++i)
mu[i] += mu[i-1], (d[i] += d[i-1]) %= mod;
}
map<int, int>MU;
inline int sum_mu(int n) {
if(n < MAXN) return mu[n];
if(MU.count(n)) return MU[n];
int re = 1;
for(int i = 2, j; i <= n; i = j+1) {
j = n/(n/i);
re = (re - 1ll * (j-i+1) * sum_mu(n/i) % mod) % mod;
}
return MU[n]=re;
}
map<int, int>D;
inline int sum_d(int n) {
if(n < MAXN) return d[n];
if(D.count(n)) return D[n];
int re = 0;
for(int i = 1, j; i <= n; i = j+1) {
j = n/(n/i);
re = (re + 1ll * (j-i+1) * (n/i) % mod) % mod;
}
return D[n]=re;
}
inline int sqr(int x) { return 1ll*x*x%mod; }
inline int solve(int n) {
int re = 0;
for(int i = 1, j; i <= n; i = j+1) {
j = n/(n/i);
re = (re + 1ll * (sum_mu(j)-sum_mu(i-1)) % mod * sqr(sum_d(n/i)) % mod) % mod;
}
return re;
}
int main() {
int n;
scanf("%d", &n);
Pre_Work(min(n, MAXN-1));
printf("%d\n", (solve(n) + mod) % mod);
}
[bzoj 4176] Lucas的数论 (杜教筛 + 莫比乌斯反演)的更多相关文章
- BZOJ 4176: Lucas的数论 [杜教筛]
4176: Lucas的数论 题意:求\(\sum_{i=1}^n \sum_{j=1}^n \sigma_0(ij)\) \(n \le 10^9\) 代入\(\sigma_0(nm)=\sum_{ ...
- bzoj 4176: Lucas的数论 -- 杜教筛,莫比乌斯反演
4176: Lucas的数论 Time Limit: 30 Sec Memory Limit: 256 MB Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么 ...
- 【XSY2731】Div 数论 杜教筛 莫比乌斯反演
题目大意 定义复数\(a+bi\)为整数\(k\)的约数,当且仅当\(a\)和\(b\)为整数且存在整数\(c\)和\(d\)满足\((a+bi)(c+di)=k\). 定义复数\(a+bi\)的实部 ...
- 【BZOJ4176】Lucas的数论-杜教筛
求$$\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}f(ij)$$,其中$f(x)$表示$x$的约数个数,$0\leq n\leq 10^9$,答案膜$10^9+ ...
- BZOJ_4176_Lucas的数论_杜教筛+莫比乌斯反演
BZOJ_4176_Lucas的数论_杜教筛+莫比乌斯反演 Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目“求 ...
- bzoj4176. Lucas的数论 杜教筛
题意:求\(\sum_{i=1}^n\sum_{j=1}^nd(ij),d是约数个数函数\) 题解:首先有一个结论\(d(ij)=\sum_{x|i}\sum_{y|j}[(i,j)==1]\) 那么 ...
- [CQOI2015][bzoj3930] 选数 [杜教筛+莫比乌斯反演]
题面: 传送门 思路: 首先我们把区间缩小到$\left[\lfloor\frac{L-1}{K}\rfloor,\lfloor\frac{R}{K}\rfloor\right]$ 这道题的最特殊的点 ...
- [51Nod 1237] 最大公约数之和 (杜教筛+莫比乌斯反演)
题目描述 求∑i=1n∑j=1n(i,j) mod (1e9+7)n<=1010\sum_{i=1}^n\sum_{j=1}^n(i,j)~mod~(1e9+7)\\n<=10^{10}i ...
- bzoj 4916: 神犇和蒟蒻 (杜教筛+莫比乌斯反演)
题目大意: 读入n. 第一行输出“1”(不带引号). 第二行输出$\sum_{i=1}^n i\phi(i)$. 题解: 所以说那个$\sum\mu$是在开玩笑么=.= 设$f(n)=n\phi(n) ...
随机推荐
- 精通react之react-router4源码分析(100代码实现router功能)
1.react-router4 是一个 react 组件 通过和 location / histroy 结合,来显示页面不同URL对应显示不同的组件 其中包含了三种路由.hash / boswer 等 ...
- IDEA中MavenWeb项目没有新建servlet文件
解决方案: https://blog.csdn.net/Delicious_Life/article/details/89515363
- day04——列表、元组、range
day04 列表 列表--list 有序,可变,支持索引 列表:存储数据,支持的数据类型很多:字符串,数字,布尔值,列表,集合,元组,字典,用逗号分割的是一个元素 id() :获取对象的内存地址 ...
- libevent源码分析一--io事件响应
这篇文章将分析libevent如何组织io事件,如何捕捉事件的发生并进行相应的响应.这里不会详细分析event与event_base的细节,仅描述io事件如何存储与如何响应. 1. select l ...
- 分布式缓存重建并发冲突和zookeeper分布式锁解决方案
如果缓存服务在本地的ehcache中都读取不到数据. 这个时候就意味着,需要重新到源头的服务中去拉去数据,拉取到数据之后,赶紧先给nginx的请求返回,同时将数据写入ehcache和redis中 分布 ...
- java之spring之整合ssh-2
这篇也是主要讲解 ssh 的整合,不同于上一篇的是它的注入方式. 这篇会采用扫描注入的方式,即去除 applicationContext-asd.xml 文件. 目录结构如下: 注意,这里只列举不同的 ...
- 支付宝支付 微信支付SDK接口不统一? 盘他!
开发过支付宝.微信支付的同学都知道,微信的支付 API 设计感觉是 Java 开发工程师写的,远不如支付宝 SDK 的接口设计用起来顺手.在这里,统一封装微信支付和支付宝支付的API,使两种支付方 ...
- 经典sql server基础语句不全
1.几个简单的基本的sql语句 选择: select * from table1 where 范围 插入: insert into table1(field1,field2) values(value ...
- 五、Linux_ping命令
ping命令用法为:“ping 参数 目标主机”.其中参数为零到多个,目标主机可以是IP或者域名. 1.每隔0.6秒ping一次,一共ping 5次: [root@aiezu.com ~]# ping ...
- USB之设备插入波形变化2
============= 本系列参考 ============= <圈圈教你玩USB>.<Linux那些事儿之我是USB> 协议文档:https://www.usb.or ...