[Bzoj 2956] 模积和 (整除分块)
整除分块
一般形式:\(\sum_{i = 1}^n \lfloor \frac{n}{i} \rfloor * f(i)\)。
需要一种高效求得函数 \(f(i)\) 的前缀和的方法,比如等差等比数列求和或对于积性函数的筛法等,然后就可以用整除分块的思想做。
题目解法
化公式变成比较方便的形式:
\(\ \sum_{i = 1}^n \sum_{j = 1}^m (n \mod i)(m \mod j), i \ne j\)
\(= \sum_{i = 1}^n \sum_{j = 1}^m (n - i \lfloor \frac{n}{i} \rfloor)(m - j \lfloor \frac{m}{j} \rfloor) - \sum_{i = 1}^{min(n, m)} (n - i \lfloor \frac{n}{i} \rfloor)(m - i \lfloor \frac{m}{i} \rfloor)\)
乘法分配律展开,化简,令 \(t = min(n, m)\) 得:
\(\ \sum_{i = 1}^n \sum_{j = 1}^m (n - i \lfloor \frac{n}{i} \rfloor)(m - j \lfloor \frac{m}{j} \rfloor) - \sum_{i = 1}^t (n - i \lfloor \frac{n}{i} \rfloor)(m - i \lfloor \frac{m}{i} \rfloor)\)
\(= \sum_{i = 1}^n \sum_{i = 1}^m nm + m\sum_{i = 1}^n \sum_{i = 1}^m j \lfloor \frac{n}{i} \rfloor + n\sum_{i = 1}^n \sum_{i = 1}^m \lfloor \frac{m}{j} \rfloor +\)
\(\sum_{i = 1}^n \sum_{i = 1}^m ij \lfloor \frac{n}{i} \rfloor \lfloor \frac{m}{j} \rfloor - \sum_{i = 1}^t nm + m \sum_{i = 1}^t i \lfloor \frac{n}{i} \rfloor - n \sum_{i = 1}^t i \lfloor \frac{m}{i} \rfloor - \sum_{i = 1}^t i^2 \lfloor \frac{n}{i} \rfloor\)
\(\sum_{i = 1}^n \sum_{i = 1}^m ij \lfloor \frac{n}{i} \rfloor \lfloor \frac{m}{j} \rfloor\) 等于 \(\sum_{i = 1}^n i \lfloor \frac{n}{i} \rfloor * \sum_{i = 1}^m j \lfloor \frac{m}{j} \rfloor\),一个一个算即可。
代码写的比较长……因为用 \(unsigned ll\) 为了避免出负数也多了很多取模……
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long u64;
const u64 mod = 19940417;
const u64 inv_6 = 3323403;
inline u64 Calc_1(u64 l, u64 r) { return (l + r) * (r - l + 1) / 2 % mod; }
inline u64 Calc_2(u64 x) { return ((x + 1) * (2 * x + 1) % mod) * (x * inv_6 % mod) % mod; }
int main(int argc, const char *argv[])
{
u64 n = 0, m = 0, t = 0, ans = 0, sum_1 = 0, sum_2 = 0;
scanf("%llu%llu", &n, &m);
ans = ((n * m % mod) * (n * m % mod) % mod);
t = min(n, m), ans = (ans + mod - (n * m % mod) * t % mod) % mod;
for(u64 tmp, l = 1, r = 1; l <= n; l = r + 1) {
tmp = n / l, r = n / tmp;
ans = (ans + mod - (Calc_1(l, r) * tmp % mod) * (m * m % mod) % mod) % mod;
sum_1 = (sum_1 + Calc_1(l, r) * tmp % mod) % mod;
}
for(u64 tmp, l = 1, r = 1; l <= m; l = r + 1) {
tmp = m / l, r = m / tmp;
ans = (ans + mod - (Calc_1(l, r) * tmp % mod) * (n * n % mod) % mod) % mod;
sum_2 = (sum_2 + Calc_1(l, r) * tmp % mod) % mod;
}
for(u64 tmp, l = 1, r = 1; l <= t; l = r + 1) {
tmp = n / l, r = min(t, n / tmp);
ans = (ans + Calc_1(l, r) * (tmp * m % mod)) % mod;
}
for(u64 tmp, l = 1, r = 1; l <= t; l = r + 1) {
tmp = m / l, r = min(t, m / tmp);
ans = (ans + Calc_1(l, r) * (tmp * n % mod)) % mod;
}
for(u64 l = 1, r = 1; l <= t; l = r + 1) {
r = min(t, min(n / (n / l), m / (m / l)));
ans = (ans + mod - (mod + Calc_2(r) - Calc_2(l - 1)) * ((n / l) * (m / l) % mod) % mod) % mod;
}
printf("%llu\n", (ans + sum_1 * sum_2) % mod);
return 0;
}
[Bzoj 2956] 模积和 (整除分块)的更多相关文章
- BZOJ 2956 模积和(分块)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2956 [题目大意] 求∑∑((n%i)*(m%j))其中1<=i<=n,1 ...
- BZOJ 2956 模积和 (数学推导+数论分块)
手动博客搬家: 本文发表于20170223 16:47:26, 原地址https://blog.csdn.net/suncongbo/article/details/79354835 题目链接: ht ...
- BZOJ 2956 模积和
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2956 题意:给出n和m.计算: 思路: i64 n,m; i64 cal(i64 m,i ...
- BZOJ2956: 模积和——整除分块
题意 求 $\sum_{i=1}^n \sum_{j=1}^m (n \ mod \ i)*(m \ mod \ j)$($i \neq j$),$n,m \leq 10^9$答案对 $1994041 ...
- bzoj 2956: 模积和 ——数论
Description 求∑∑((n mod i)*(m mod j))其中1<=i<=n,1<=j<=m,i≠j. Input 第一行两个数n,m. Output 一个整数表 ...
- 【BZOJ】2956: 模积和
题意 求\(\sum_{i=1}^{n} \sum_{j=1}^{m} (n \ mod \ i)(m \ mod \ j)[i \neq j] \ mod \ 19940417\), \((n, m ...
- BZOJ2956: 模积和(数论分块)
题意 题目链接 Sol 啊啊这题好恶心啊,推的时候一堆细节qwq \(a \% i = a - \frac{a}{i} * i\) 把所有的都展开,直接分块.关键是那个\(i \not= j\)的地方 ...
- P2260 [清华集训2012]模积和
P2260 [清华集训2012]模积和 整除分块+逆元 详细题解移步P2260题解板块 式子可以拆开分别求解,具体见题解 这里主要讲的是整除分块(数论分块)和mod不为素数时如何求逆元 整除分块:求Σ ...
- 【BZOJ】2956:模积和
Time Limit: 10 Sec Memory Limit: 128 MB Description 求∑∑((n mod i)*(m mod j))其中1<=i<=n,1<=j ...
随机推荐
- 如何快速清理 docker 资源
如果经常使用 docker,你会发现 docker 占用的资源膨胀很快,其中最明显也最容易被察觉的应该是对磁盘空间的占用.本文将介绍如何快速的清理 docker 占用的系统资源,具体点说就是删除那些无 ...
- 手把手教新手小白在window把自己的项目上传到github
作为一个开发者,写博客,上传项目到github好像是不可不会的技能,很多有经验的老司机都会这么建议你.本宝宝第一次要把项目传到github的时候,确实有点蒙蔽,什么鬼,传个东西有必要这么难吗? git ...
- 安装Docker时错误提示 "could not change group /var/run/docker.sock to docker: group docker not found"的解决方案
安装Dock服务,主要命令是 yum install docker. 但是在启动的时候报错:warning msg="could not change group /var/run/doc ...
- SQL Server数据库文件与文件组总结
文件和文件组概念 关于文件与文件组,简单概括如下,详情请参考官方文档"数据库文件和文件组Database Files and Filegroups"或更多相关资料: 数据文件概念: ...
- vue框架构建项目流程
构建项目流程: 1.全局查询:node -v 2.全局初始化:npm install --global vue-cli 3.模块化工程:vue init webpack myapp--->y,n ...
- [RHEL 7]ISCSI服务端及客户端连接配置
环境RHEL7.4 1.搭建服务器端主机环境 网络配置 网卡eth0 10.0.0.1 网卡eth1 10.1.0.1 网卡eth2 10.2.0.1 网卡eth3 10.3.0.1 硬盘配置 添加一 ...
- Carthage入门篇-安装和使用
在iOS开发过程中,用到最多的三方库管理工具也许是Cocoapods.Cocoapods会自动为你创建一个workspace,然后自动将你要用到的三方库集成到Project中,而整个过程,你只需要对P ...
- idea 右键无java class选项
项目中新建module之后,要在该目录下新增java Class文件,右键——>New发现无Java Class选项. File –Project Structure或者ctrl+alt+shi ...
- 好程序员web前端分享12个CSS高级技巧汇总
好程序员web前端分享下面这些CSS高级技巧,一般人我可不告诉他哦. 使用 :not() 在菜单上应用/取消应用边框 给body添加行高 所有一切都垂直居中 逗号分隔的列表 使用负的 nth-chil ...
- 初识gauge自动化测试框架(二)
看到一些同学对该工具有点一兴趣,那么我将继续介绍Gauge自动化测试工具. Gauge本质上一个BDD(Behavior Driven Development)测试框架.所以,首先你要了解BDD的操作 ...