牛客练习赛25 A-因数个数和

文章目录

  • 题目:
  • 分析:
  • 代码:


题目:

传送门


分析:

首先是一个比较容易理解的数论知识:
在 n 以 内 所 有 数 的 因 数 和 = ∑ i = 1 n n / i 在n以内所有数的因数和=\sum_{i=1}^{n}n/i n=i=1nn/i
那么 x x x n n n的因数,那么 n / x n/x n/x肯定也是 n n n的因数
我们可以将上面的公式变为( w w w n n n的算术平方根)
( ∑ i = 1 w n / i ) ∗ 2 (\sum_{i=1}^{w}n/i)*2 (i=1wn/i)2
但当我们自信满满的去做时,会发现答案太大了,这是为什么呢
——很显然,当 n = 16 n=16 n=16 i = 4 i=4 i=4时,我们就会多算一次 4 4 4
而其他的平方数也是如此
故我们应减去 w w w,但这样还是 W A WA WA
这又是为什么呢
我们不妨来举个例子:
对于数字1,有1个因数(1),我们简单乘以2,多计算了1次1

对于数字2,有2因数(1,2),我们简单乘以2,多计算了1次1,1次2

对于数字3,有2因数(1,3),我们简单乘以2,多计算了1次1,1次3

对于数字4,有2因数(1,2,4),我们简单乘以2,多计算了1次1,1次2,1次4

对于数字5,有2因数(1,5),我们简单乘以2,正好

对于数字6,有2因数(1,2,3,6),我们简单乘以2,多计算了1次2,1次3

对于数字7,有2因数(1,7),我们简单乘以2,正好

对于数字8,有2因数(1,2,4,8),我们简单乘以2,多计算了1次2,1次4

对于数字9,有2因数(1,3,9),我们简单乘以2,多计算了1次3

对于数字10,有2因数(1,2,5,10),我们简单乘以2,正好

对于数字11,有2因数(1,11),我们简单乘以2,正好

对于数字12,有2因数(1,2,3,4,6,12),我们简单乘以2,1次3,1次4

对于数字13,有2因数(1,13),我们简单乘以2,正好

对于数字14,有2因数(1,2,7,14),我们简单乘以2,正好

对于数字15,有2因数(1,3,5,15),我们简单乘以2,正好

对于数字16,有2因数(1,2,4,8,16),我们简单乘以2,多计算了1次4
加起来正好是 1   w 1~w 1 w w w w个因数,每一个都多计算了 w w w次。所以我们一共多计算了 w 2 w^2 w2
所以将我们以上所有内容总结起来,得出 A C AC AC公式:
( ∑ i = 1 w n / i ) ∗ 2 − w 2 (\sum_{i=1}^{w}n/i)*2-w^2 (i=1wn/i)2w2


代码:

#include
#include
#include
#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define h happy
#define XJQ 牛逼
#define HSZGB 欠老子400块 
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
int main()
{
	int q=read();
	LL ans=0;
	while(q--)
	{
		int x=read();
		int s=sqrt(x);
		ans=0;
		for(int i=1;i<=s;i++) ans+=x/i;
		printf("%lld\n",ans*2-s*s);
	}
	return 0;
}

你可能感兴趣的:(数论)