In mathematics, the Pythagorean theorem — is a relation in Euclidean geometry among the three sides of a right-angled triangle. In terms of areas, it states:
In any right-angled triangle, the area of the square whose side is the hypotenuse (the side opposite the right angle) is equal to the sum of the areas of the squares whose sides are the two legs (the two sides that meet at a right angle).
The theorem can be written as an equation relating the lengths of the sides a, b and c, often called the Pythagorean equation:
a2 + b2 = c2
where c represents the length of the hypotenuse, and a and b represent the lengths of the other two sides.
Given n, your task is to count how many right-angled triangles with side-lengths a, b and c that satisfied an inequality 1 ≤ a ≤ b ≤ c ≤ n.
Input
The only line contains one integer n (1 ≤ n ≤ 104) as we mentioned above.
Output
Print a single integer — the answer to the problem.
Examples
Input
5
Output
1
Input
74
Output
35
题意:求出n以内的勾股数组数 |
思路:
这题暴力当然可以,但是这里介绍一种更高效的方法——高斯素数。我用这个方法本题只跑了124ms,也就是说数据量再乘10也可以A掉。
介绍之前先给出一个洛谷的高斯素数模板题:圆上的整点
这是一个和本题类似的题,给你一个r,问圆上有多少整数点满足a2 + b 2 = r2 。利用高斯素数的性质,将一个数分解成其质因数相乘的形式之后(唯一分解定理),若其中的质因数可以分解为高斯素数,则对答案的贡献就是其指数+1。那怎么判断一个数是不是高斯素数呢?
1.满足4n+1的质因数可以分解为高斯素数
2.若该数是4n+3的形式(只有这4n+1和4n+3这两种情况,因为质数首先是奇数),则指数为奇数时不可能有解,反之不变。
所以对于这题只需要枚举一次1->n然后对每个数看能分解出的整数解即可。时间复杂度O(nlogn)。
关于算法的推导和理解视频:传送门
AC代码:
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)