[HAOI2008]圓上的整點
神仙題
求滿足\(x^2+y^2=R^2(x,y\in\mathbb{Z})\)的數對$(x,y)個數
高斯整數:是個復數,形如\(a+bi\),其中\(a,b\)均為整數
高斯質數是高斯整數,不能分成高斯整數的乘積
那就是在求模長為\(R^2\)的高斯整數個數
顯然高斯整數模長可以表示成\((a+bi)(a-bi)\),即一對共軛復數的積
考慮\(R^2=(a+bi)(a-bi)\)的方案數,令\(N=R^2\)(事實上N不是完全平方數這題也能做)
先將N分解成若干個質數之積
隨意假設\(N=3^2*5^2\)
還要繼續分下去,分成若干個高斯質數
然后這里用到一個結論:形如\(4n+1\)的質數能分成兩個高斯質數的乘積,形如\(4n+3\)的不行(視頻里也沒有說為啥)
所以上面的n可以分成\(3^2*(2+i)(2-i)(2+i)(2-i)\)
要把這些分成兩組,每組都在另一邊有它的共軛復數對應
\(3^2\)只能一邊放一個\((2+i)^2(2-i)^2\)有3種方法(左邊放0,1,2個\((2+i)\))
於是就有3種分法,乘4以后\(N=225\)的答案就是12
繼續看幾個例子:
- \(N=3^3*5^2\)時,兩邊的3無論如何也不能平衡,答案是0
- \(N=3^2*5^3\)時,左邊可以放0,1,2,3個\((2+i)\),答案是4(*4=16)
- \(N=3^2*5^3*13^4\)時,左邊可以放0,1,2,3個(2+i)和0,1,2,3,4個(3+2i),答案就是20(×4=80)
可以發現這樣的規律:
將N分解質因數
ans=1
for i in 所有質因數
if i形如4n+1:
if i的次數為奇數:
ans=0 # 無法安排這個質因數使得兩邊是共軛復數
else:pass # 什么也沒有發生,這個質因數只有一種放法,就是兩邊放同樣多個
else:ans*= i的次數+1 # i=(a+bi)(a-bi),左邊可以放0~次數個(a+bi)
然后就結束了。
嗎?
如果有質因數是2咋搞啊。。。
事實上不需要搞這個,因為2可以分成\((1+i)(1-i)\),只能是一個在左一個在右,然而交換這兩個數實際上是一邊\(*\frac{1+i}{1-i}=i\)另一邊\(/\frac{1+i}{1-i}=i\),實際上和最后的答案×4是一樣的操作,所以質因數2對答案並沒有影響
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define il inline
#define vd void
typedef long long ll;
il int gi(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
int main(){
int n=gi();
long long ans=1;
for(int i=2;i*i<=n;++i)
if(n%i==0){
int p=0;while(n%i==0)n/=i,++p;
if(i%4==1)ans*=2*p+1;
}
if(n>1){
if(n%4==1)ans*=3;
}
printf("%lld\n",ans*4);
return 0;
}
還有,實際上是不會有0出現的,因為輸入的是個整數,平方之后所以質因子次數都是偶數