【CodeForces 304A 】Pythagorean Theorem II 高斯素数 高效算法

本文介绍了如何利用高斯素数的性质解决CodeForces 304A问题,该问题要求统计在给定范围内满足勾股定理的直角三角形数量。通过分析高斯素数的特性,提出了一种时间复杂度为O(nlogn)的解决方案,使得算法能在大数据量下依然有效。
摘要由CSDN通过智能技术生成

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)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值