博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P2261余数求和
阅读量:4588 次
发布时间:2019-06-09

本文共 1298 字,大约阅读时间需要 4 分钟。

再一次见证了分块的神奇用法,在数论里用分块思想。

我们要求 $ ans = \sum\limits ^{n} _{i=1} (k % i) $ ,如果我没看错,这个题的暴力有 $ 60 $ 分,当然,不甘平凡的我们怎么能为 $ 60 $ 分折腰,我们来看正解打法。

我们要知道 $ a % b = a-b*\lfloor\frac{a}{b}\rfloor$ 。.

我们代入后得到:

$ ans = \sum\limits^{n}_{i=1}(k-i\lfloor\frac{k}{i}\rfloor) = n*k-\sum\limits^{n}_{i=1}(i * \lfloor\frac{k}{i}\rfloor) $

然后我们用分块做,我们最后计算 $ n * k $ 减去每一段的和就好了。

开始枚举左端点,根据 $ k $ 计算出右端点:

若 $ \lfloor\frac{k}{l}\rfloor \neq 0 $ , $ r = min(\lfloor\frac{k}{\lfloor\frac{k}{l}\rfloor}\rfloor , n) $ 。

若$ \lfloor\frac{k}{l}\rfloor=0 $ ,$ r=n $。

最后计算每一块的和:

$ sum = \lfloor\frac{k}{l}\rfloor * (r-l+1) *(l+r) / 2$。

#include 
#include
#include
#include
using namespace std;inline long long read(){ char ch = getchar(); long long f = 1 , x = 0; while(ch > '9' || ch < '0'){if(ch == '-')f = -1;ch = getchar();} while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + ch - '0';ch = getchar();} return x * f;}long long n,k;long long ans;int main(){ n = read(); k = read(); ans = n * k; for(int l=1,r;l<=n;l=r+1){ if(k / l != 0) r = min(k / (k / l) , n); else r = n; ans -= (k / l) * (r - l + 1) * (l + r) / 2; } printf("%lld\n",ans); return 0;}

转载于:https://www.cnblogs.com/Stephen-F/p/9885948.html

你可能感兴趣的文章
SQL Server 触发器
查看>>
css优先级计算规则
查看>>
Asp.Net Web API 2第十五课——Model Validation(模型验证)
查看>>
Silverlight 4 MVVM开发方式(三)动态换皮
查看>>
ExtJs中OA管理中组织和用户关系左右选择组件的运用
查看>>
【原创】关于高度自适应问题
查看>>
Tomcat JMX
查看>>
2019 年,容器技术生态会发生些什么?
查看>>
ubuntu安装hive
查看>>
Java NIO Selector(八)
查看>>
Hibernate入门(三)—— 一对多、多对多关系
查看>>
Openstack中查看虚拟机console log的几种方法
查看>>
科技创新平台年报系统利益相关者分析
查看>>
家庭作业第三章3.57
查看>>
ERROR! MySQL manager or server PID file could not be found!
查看>>
nginx server_name匹配顺序
查看>>
数据备份希望使用gistore备份mongo数据
查看>>
【杂谈】新学年的第一篇博客
查看>>
黑马程序员--抽象类与接口
查看>>
IaaS,PaaS,SaaS 的区别
查看>>