2020牛客寒假算法基础集训营2——E.做计数【推公式】

题目传送门


题目描述

这一天,牛牛与 牛魔王相遇了――然而这并不在 牛牛期望之中。
牛魔王不出意料又给 牛牛一道看似很难的题目:求有多少个不同的正整数三元组 ( i , j , k ) \text{}(i,j,k) 满足 i + j = k \sqrt i+\sqrt j=\sqrt k ,且 i × j n i\times j\leq n
牛牛并不会做,你能略施援手吗?
当两个三元组 ( i 1 , j 1 , k 1 ) , ( i 2 , j 2 , k 2 ) \text{}(i_1,j_1,k_1), (i_2,j_2,k_2) 满足 i 1 i 2 i_1\neq i_2 j 1 j 2 j_1\neq j_2 k 1 k 2 k_1\neq k_2 时它们被认为是不同的。


输入描述:

第一行,一个正整数 n。

保证 1 n 4 × 1 0 7 1\leq n\leq 4\times 10^7


输出描述:

输出一行,一个整数表示答案。


输入

1


输出

1


说明

(1,1,4)


题解

  • 两边平方,得 i + j + 2 i j = k i+j+2\sqrt{ij}=k ,显然仅当 i,ji,j 都是整数且 i j ij 为完全平方数时才会对应一个符合条件的 k k

  • 枚举 [ 1 , n ] [1,n] 中所有的完全平方数(完全平方数可以表示为 x 2 x^2 ,只需要枚举 x x ),再枚举这个完全平方数的因数,统计答案。

  • O ( n ) O(\sqrt n) 枚举完全平方数 O ( n ) O(\sqrt n) 枚举因数,时间复杂度 O ( n ) O(n) ,可以进一步优化。


AC-Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int main() {
	int n;	cin >> n;	ll ans = 0;
	for (int i = 1; i * i <= n; ++i) {
		int num = 0;
		for (int j = 1; j <= i; ++j)
			if (i * i % j == 0)	ans += 2;
		--ans;
	}
	cout << ans << endl;
}
发布了157 篇原创文章 · 获赞 99 · 访问量 9814

猜你喜欢

转载自blog.csdn.net/Q_1849805767/article/details/104202490