题目描述
给定一个整数n,分别求n范围内的(x,y,z<=n)本原的毕达哥拉斯三元组的个数,以及n以内且毕达哥拉斯三元组不涉及的数的个数。
输入格式
输入数据有多组,每组占一行包含一个整数n(n<=10^6)。
输出格式
对于每组输入,输出两个整数分别代表n范围内的(x,y,z<=n)本原的毕达哥拉斯三元组的个数以及n以内且毕达哥拉斯三元组不涉及的数的个数。
样例数据
样例输入
10
25
100
样例输出
1 4
4 9
16 27
数据规模
N<=1000000
题目分析
特殊的不定方程:毕达哥拉斯三元组
由定理:x、y、z构成一个本原的毕达哥拉斯三元组且y是偶数,当且仅当存在互素的正整数m、n,其中m、n奇偶性不同,并且满足:
x=m^2-n^2
y=2mn
z=m^2+m^2
因此枚举m、n,Hash暴力求解
源代码
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
typedef long long LL;
inline const LL Get_Int() {
LL num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
LL Limit,cnt,ans1,ans2,Hash[1000005];
LL Gcd(LL x,LL y) {
if(y==0)return x;
else return Gcd(y,x%y);
}
int main() {
while(scanf("%lld",&Limit)!=EOF) {
cnt=ans1=ans2=0;
memset(Hash,0,sizeof(Hash));
for(int n=1; n<=sqrt(Limit); n++)
for(int m=n+1; m<=sqrt(Limit); m++) {
if(m*m+n*n>Limit)break;
if((m%2!=n%2)&&(Gcd(m,n)==1)) {
LL x=m*m-n*n,y=2*m*n,z=m*m+n*n;
ans1++;
int Now=1;
while(Now*z<=Limit) {
Hash[Now*x]=1;
Hash[Now*y]=1;
Hash[Now*z]=1;
Now++;
}
}
}
for(int i=1; i<=Limit; i++)
if(!Hash[i])ans2++;
printf("%lld %lld\n",ans1,ans2);
}
return 0;
}