51 NOD:1225 余数之和(推公式)
来源:互联网 发布:linux 挂载分区成功 编辑:程序博客网 时间:2024/05/21 22:45
传送门
1225 余数之和
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注
F(n) = (n % 1) + (n % 2) + (n % 3) + …… (n % n)。其中%表示Mod,也就是余数。
例如F(6) = 6 % 1 + 6 % 2 + 6 % 3 + 6 % 4 + 6 % 5 + 6 % 6 = 0 + 0 + 0 + 2 + 1 + 0 = 3。
给出n,计算F(n), 由于结果很大,输出Mod 1000000007的结果即可。
Input
输入1个数N(2 <= N <= 10^12)。
Output
输出F(n) Mod 1000000007的结果。
Input示例
6
Output示例
3
解题思路:
首先我们知道的是求n 的余数 n - [n/i]*i(在这里”[]”表示的是取整的意思)那么我们要求的余数之和就是 sigma(n-[n/i]*i)也就是
我们知道的是 当 n/i > sqrt(n)的时候n/i的数值只出现一次,然后我们看一下这个题的数据范围,也知道暴力解决不了,那么我们就得采用的是O(sqrt(n))的算法了,那么我们现在从 i=1循环到 i=sqrt(n),对于n/i>sqrt(n)的来说直接暴力求解就行了,因为n/i要是想>sqrt(n)话,i一定是 < sqrt(n)的 那么我们剩下的sqrt(n)-n怎么求呢,我们可以观察一下,在 i = sqrt(n)-n的范围内 n/i 一定是 <= sqrt(n)的,那么我们可以根据这个规律来求,因为每次他们都是连续递增出现的,所以可以将 [n/i] * i 看作一个等差数列,在这个数列中 因为在一段数中[n/i]是不变的,变化的只有i,而且i是连续递增变化的,那么首项是n/(i+1)+1,末项是 n/i,个数是 n/i - n/(i+1) ,别忘记乘以i,然后除以2(这里需要用到逆元),其实在纸上一推就很明显了,再结合代码来看就很容易明白了:
上代码:
#include <iostream>#include <cmath>#include <cstdio>#include <cstring>#include <cstdlib>using namespace std;typedef long long LL;const LL MOD = 1000000007;void Ex_gcd(LL a, LL b, LL &x, LL &y){ if(b == 0) { x = 1; y = 0; return; } LL x1, y1; Ex_gcd(b, a%b, x1, y1); x = y1; y = x1-(a/b)*y1;}int main(){ /**求的逆元 LL inv, y; Ex_gcd(2, MOD, inv, y); inv = (inv%MOD+MOD)%MOD; **/ LL inv = 500000004; LL n; while(~scanf("%I64d",&n)) { LL ans = ((n%MOD) * (n%MOD)) % MOD;///n^2 LL m = (LL)sqrt(n);///放在外面省时间 for(LL i=1; i<=m; i++) { if(n/i == m)///特判一下sqrt(n) { ans = ((ans-m*m)%MOD+MOD)%MOD; continue; } LL tmp = (n/i+n/(i+1)+1)%MOD;///n/i是等差数列的第一项,n/(i+1)+1最后一项 LL cur = (i*(n/i-n/(i+1)))%MOD;///n/i-n/(i+1)是个数 tmp = ((tmp*cur)%MOD*inv)%MOD; tmp = (tmp+(n/i)*i)%MOD; ans = ((ans-tmp)%MOD+MOD)%MOD; } printf("%I64d\n",ans); } return 0;}
0 0
- 51 NOD:1225 余数之和(推公式)
- 51nod 1225 余数之和
- 51nod 1225 余数之和
- 51NOD-1225 余数之和
- 51Nod-1225-余数之和
- 51 Nod 1225 余数之和
- 51nod 1225 余数之和
- 51nod 1225 余数之和(根号n枚举)
- 51nod 1225 余数之和 (分块思想)
- [数论] 51Nod 1225 余数之和
- 51nod 1168 . 余数之和
- 51Nod 1225 余数之和(除法分块+等差数列)
- [分块]51 Nod——1225 余数之和
- 51nod-1225-余数求和(分块)
- 1225 余数之和
- 51nod树的距离之和 DFS+递推
- 51 NOD 1189 阶乘分数(素因子分解+推公式+求逆元)
- 51NOD 1632 B君的连通(推公式)——算法马拉松16
- linux内核编译
- BigDecimal 乘法问题
- hjr理解-CPU,MCU,MPU,DSP,MCU,ARM.SOC,SOPC,FPGA
- Android 之startActivityForReult 与 onActivityResult简介
- Android——SharedPreferences存储数据方式
- 51 NOD:1225 余数之和(推公式)
- iOS8 屏幕横竖屏分析
- 富文本字符串颜色改变效果
- iOS - Xcode -Target , PROJECT 区别
- Blade模板引擎-常用语法格式
- 在前端弹出后台的错误信息
- java操作<Map转换List——>list集合重新排序—>List集合转换成JSON>
- Java--银行账户存取款线程设计1(交互线程)
- linux命令