解方程
题目描述
小象同学在初等教育时期遇到了一个复杂的数学题,题目是这样的:
给定自然数 nn,确定关于 x, y, z的不定方程
的所有自然数解。
当时的小象同学并不会做这道题。多年后,经过高等教育的洗礼,小象同学发现这道题其实很简单。小象同学认为你一定也会做这道题,所以把这道题留给了你。为了便于输出,你不需要输出每一组解 (x, y, z),你只需要给出解的数量和所有解的 xyz 之和对 (10^9+7)取模的值即可。注意,解的数量不对 (10^9+7)取模。
输入描述
输入包含多组测试数据。输入的第一行包含一个正整数 TT (1 \leq T \leq10^4),表示测试数据的组数。接下来依次描述每组测试数据,对于每组测试数据:
仅一行,包含一个非负整数 n (0 <=n<=10^9),含义如题面所示。
输出描述
对于每组数据,输出一行。若方程有无穷多组自然数解,则在这一行输出 \text{``infty’’}(不含引号),否则在这一行输出两个整数,其中第一个整数表示方程的解数,第二个整数表示所有解的 xyz 之和对 (10^9+7) 取模的值,这两个整数之间用恰好一个空格隔开,行末不要有多余的空格。
样例输入 1
3
6
12
24
样例输出 1
0 0
1 12
2 72
提示
当 n = 12n=12 时,方程唯一的解为 x = 4x=4, y = 1y=1, z = 3z=3。
当 n = 24n=24 时,方程的两组解为 x = 5x=5, y = 2y=2, z = 3z=3 和 x = 7x=7, y = 1y=1, z = 6z=6。
思路:
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e9+7;
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n;
int ans=0;
int cnt=0;
scanf("%d",&n);
int p=sqrt(n);
if(p*p==n){
puts("infty");continue;
}
if(n%4!=0){
puts("0 0");continue;
}
n/=4;
for(int y=1;ll(y*y)<=n;y++){
if(n%y==0){
cnt++;
ans=(ans+((n/y+y)*ll(n))%N)%N;
}
}
printf("%d %d\n",cnt,ans);
}
return 0;
}