洛谷 P2424 约数和
题目背景
Smart最近沉迷于对约数的研究中。
题目描述
对于一个数X,函数f(X)表示X所有约数的和。例如:f(6)=1+2+3+6=12。对于一个X,Smart可以很快的算出f(X)。现在的问题是,给定两个正整数X,Y(X<Y),Smart希望尽快地算出f(X)+f(X+1)+……+f(Y)的值,你能帮助Smart算出这个值吗?
输入输出格式
输入格式:
输入文件仅一行,两个正整数X和Y(X<Y),表示需要计算f(X)+f(X+1)+……+f(Y)。
输出格式:
输出只有一行,为f(X)+f(X+1)+……+f(Y)的值。
输入输出样例
输入样例#1:
2 4
输出样例#1:
14
输入样例#2:
123 321
输出样例#2:
72543
说明
对于20%的数据有1≤X<Y≤105。
对于60%的数据有1≤X<Y≤1*107。
对于100%的数据有1≤X<Y≤2*109。
前面做过一个约数个数的问题 点击就送
这题就是求[l,r]的约数和
也就是 1~r 减 1~l-1的约数和
但是直接用上题方法会T成狗
于是我们发现有些因子出现次数是相同的
比如 若 n=8
那 1~8出现次数分别为 8 4 2 2 1 1 1 1
出现次数相同的区间右端点=n/(n/l)
我们可以把出现次数相同的一起算 (大佬说这叫乘法原理)
直接输出lld 出现了蜜汁错误
于是改了输出优化
#include <cstdio> #include <cctype> typedef long long LL; LL x,y; inline void Read(LL &x) { register char ch=getchar(); for(x=0;!isdigit(ch);ch=getchar()); for(;isdigit(ch);x=x*10+ch-'0',ch=getchar()); } LL solve(LL x) { LL l=1,r,ret=0; for(;l<=x;l=r+1) { r=x/(x/l); ret+=x/l*(r+l)*(r-l+1)/2; } return ret; } void print(LL ans) { if(ans/10) print(ans/10); putchar(ans%10+'0'); } int Main() { Read(x); Read(y); print(solve(y)-solve(x-1)); return 0; } int sb=Main(); int main(int argc,char *argv[]){;}
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。