題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=6441
思路:由費馬大定理知當和時等式是不成立的,而是可以直接輸出答案的,所以只需考慮的情況,由數論中的本原勾股數組知:令構造出最基礎的,然後由它進行翻倍就可以預處理出題目數據範圍內的所有組合。
AC代碼:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,a,b,c;
const int maxn=4e6+10;
struct node
{
ll b,c;
bool flag;
}ans[maxn];
void presolve()//本原勾股數組預處理
{
int maxx=40000;
ll tmpa,tmpb,tmpc;
for(ll s=1;s<maxx;s+=2){
for(ll t=1;t<s;t+=2){
if(__gcd(s,t)!=1){
break;
}
tmpa=s*t;
tmpb=(s*s-t*t)/2;
tmpc=(s*s+t*t)/2;
if(tmpa>maxx||tmpa&1==0||tmpb&1==1||tmpc&1==0){
break;
}
ans[tmpa].b=tmpb;
ans[tmpa].c=tmpc;
ans[tmpa].flag=true;
if(tmpb<=maxx){
ans[tmpb].b=tmpa;
ans[tmpb].c=tmpc;
ans[tmpb].flag=true;
}
for(ll i=1;i*tmpa<=maxx;i++){
ans[i*tmpa].b=i*tmpb;
ans[i*tmpa].c=i*tmpc;
ans[i*tmpa].flag=true;
if(i*tmpb<=maxx){
ans[i*tmpb].b=i*tmpa;
ans[i*tmpb].c=i*tmpc;
ans[i*tmpb].flag=true;
}
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
presolve();
while(t--){
scanf("%lld%lld",&n,&a);
if(n==0||n>2){//費馬大定理
printf("-1 -1\n");
}
else if(n==1){
printf("1 %lld\n",a+1);;
}
else{
if(ans[a].flag){
printf("%lld %lld\n",ans[a].b,ans[a].c);
}
else{
printf("-1 -1\n");;
}
}
}
return 0;
}
/*
1
2 3
*/
參考:https://blog.csdn.net/Fire_to_cheat_/article/details/82107035
https://www.cnblogs.com/scau20110726/archive/2013/01/18/2867074.html