洛谷

一看就知道是一个数学题。嘿嘿~

讲讲各种分的做法吧。

30分做法:不知道,这大概是这题的难点吧!

60分做法:

一是直接暴力,看下代码吧~

#include <bits/stdc++.h>
using namespace std;
typedef int _int;
#define int long long _int main()
{
int n,k,ans=0;
cin>>n>>k;
for (int i=1;i<=n;++i) {
ans+=(k%i);
}
cout<<ans;
return 0;
}

第二种做法非常接近正解。

首先显然\(k~mod~i=k-\lfloor \frac{k}{i} \rfloor*i\)。

所以我们马上一波转化,\(\sum_{i=1}^{n}k~mod~i=n*k-\sum_{i=1}^{n}\lfloor \frac{k}{i} \rfloor*i\)。

那么这一截\(\sum_{i=1}^{n}\lfloor \frac{k}{i} \rfloor*i\)怎么求呢?

这个时候,直觉会告诉我们,\(\lfloor \frac{k}{i} \rfloor*i\)很有问题。

因为是向下取整,所以会有许多\(\lfloor \frac{k}{i} \rfloor\)是一样的。于是就会有一个一个的区间。

对于每个这样的区间,在乘一个\(i\)后,显然是一个等差数列。

不信看这个:

\((int)8/3=(int)8/4=2~~~~=>~~~~8/3*3+2=8/4*4\)

所以我们可以枚举\(i\),对于每一个\(i\),求出\(t=k/i\),

令\(l=i,r=min(n,k)\)二分,如果\(mid/i=t,l\)扩大,否则\(r\)缩小。

找到后直接等差数列求和。

最后使\(i=r+1\)。这样表面时间复杂度是\(O(\sqrt{n}*log(n))\)。

实则不然,因为我们的\(i\)跳跃的距离基本上很小很小,所以这代码比\(O(n)\)还慢!

看下代码吧!

#include <bits/stdc++.h>
using namespace std;
typedef int _int;
#define int long long int n,k,ans; _int main()
{
cin>>n>>k;
ans=n*k;
for (int i=1;i<=min(n,k);++i) {
int l=i,r=min(n,k),t=k/i,j=i;
while (l<=r) {
int mid=(l+r)/2;
if (mid/i==t) l=mid+1,j=mid;
else r=mid-1;
}
int a1=t*i,an=a1+(j-i)*t,g=j-i+1;
ans-=(g*(a1+an)/2);
i=j;
}
cout<<ans;
return 0;
}

100正解:

有了上面第二个60分做法的思路,正解就不言而喻了。

只要把\(log(n)\)找区间改成\(O(1)\)就好了。

具体怎么改呢?

我们同样的枚举\(i\),假设区间为\([l,r]\),那么\(l=i\)显然,然后就剩\(r\)有点难搞了。

想想,我们每一段的公差都是\(\lfloor \frac{k}{i} \rfloor\),那么显然当\(k~mod~i=0\)时,\(r\)截止。

所以,\(r=k/(k/l)\)。

那么,就完结了,上代码!真正的极简AC难懂~

#include <bits/stdc++.h>
using namespace std;
typedef int _int;
#define int long long
int n,k,ans;
_int main()
{
cin>>n>>k;
ans=n*k;
for (int i=1;i<n;++i) {
int l=i,t=k/l,r=t?min(n,k/t):n;
int a1=t*l,an=a1+(r-l)*t,g=r-l+1;
ans-=(g*(a1+an)/2);
i=r;
}
cout<<ans;
return 0;
}

最新文章

  1. Hadoop日常维护系列——Hadoop添加删除节点
  2. PHP_Cli模式初涉——转载一篇
  3. 漫谈Linux内核哈希表(1)
  4. MySQL创建一个具有root权限的用户
  5. CocoSocket开源下载与编写经验分享
  6. [51单片机] nRF24L01 无线模块 测试 按键-灯-远程控制
  7. 【Bootstrap基础学习】02 Bootstrap的布局组件应用示例
  8. Linux大文件分割split和合并cat使用方法
  9. SQL批量修改表名
  10. leetcode@ [208] Implement Trie (Prefix Tree)
  11. SQL Server数据库---》增删查改
  12. 华为OJ之最长公共子串
  13. 如何在本地同时管理github仓库和codingnet仓库?
  14. Cocos 2d TestCPP 学习
  15. 第 7 章 多主机管理 - 047 - 管理 Machine
  16. AC自动机(病毒侵袭 )
  17. Python的容器、生成器、迭代器、可迭代对象的家谱
  18. Spark2 Dataset多维度统计cube与rollup
  19. 《C语言程序设计》指针篇&lt;二&gt;
  20. (连通图 模板题)迷宫城堡--hdu--1269

热门文章

  1. Python 的条件语句和循环语句
  2. redis 使用内存超过maxmemory
  3. NIO之阻塞IO与非阻塞IO(包含Selector使用)
  4. NIO之Channel聚集(gather)写入与分散(scatter)读取
  5. nginx源码学习_数据结构(ngx_str_t)
  6. mysql命令:set sql_log_bin=on/off
  7. oracle中查看sql语句的执行计划
  8. TCP/IP笔记(一)网络基础知识
  9. hdu 4272 LianLianKan 状态压缩
  10. 简单介绍一下vue2.0