BZOJ 1041: [HAOI2008]圆上的整点 (高斯整数,高斯质数,圆上整点数)

在这里插入图片描述

引入一个函数: h ( x ) h(x) h(x)
{ h ( x ) = 1 , [ x % 4 = 1 ] h ( x ) = − 1 , [ x % 4 = 3 ] h ( x ) = 0 , [ 其 它 ] \left\{\begin{matrix} &h(x) = 1 ,[x \% 4=1] \\ &h(x) = -1,[x \%4 = 3]\\ &h(x) = 0,[其它] \end{matrix}\right. h(x)=1[x%4=1]h(x)=1[x%4=3]h(x)=0,[]

h ( x ) h(x) h(x) 具有积性,且是一个完全积性函数,若 z = x ∗ y , p ( z ) = p ( x ) ∗ p ( y ) z = x * y,p(z) = p(x) * p(y) z=xyp(z)=p(x)p(y)

引入高斯整数:即二维平面的整数点,表示为复数形式,例如 ( 3 , 4 ) = 3 + 4 i (3,4) = 3 + 4i (3,4)=3+4i
x 2 + y 2 = r 2 x^2 + y^2 = r^2 x2+y2=r2,令 z = r 2 z = r^2 z=r2,当 z z z 可以分成两个数的平方和时 半径为 z \sqrt z z 上的圆必经过整点
根据费马平方和定理: 4 n + 1 4n + 1 4n+1 类型的质数可以分成两个数的平方和, 4 n + 3 4n + 3 4n+3类型的质数则无法分成两个数的平方和。

例如 5 = 2 2 + 1 2 5 = 2^2 + 1^2 5=22+12,将它写成高斯整数相乘的形式: ( 2 + i ) ∗ ( 2 − i ) (2 + i)*(2-i) (2+i)(2i) 2 + i 2+i 2+i 2 − i 2-i 2i都是不可再分的高斯整数,也称为高斯质数, 4 n + 3 4n + 3 4n+3类型的质数也是高斯质数,例如 7 7 7 ,可以写成 7 + 0 i 7 + 0i 7+0i

对半径为 z \sqrt z z 的圆,问题转变成,可以在这个圆上找到多少个高斯整数,使得它和它的共轭复数的乘积等于 z z z

首先对 z 进行质因子分解, z = p 1 k 1 ∗ p 2 k 2 ∗ p n k n z = p_1^{k_1}*p_2^{k_2}*p_n^{k_n} z=p1k1p2k2pnkn,对每一个 p p p,若它不是 4 n + 3 4n + 3 4n+3型的质数,则可以分成两个更小的互为共轭复数的高斯整数的乘积 : ( a + b i ) ∗ ( a − b i ) (a + bi) * (a-bi) (a+bi)(abi)

例如 25 = 5 ∗ 5 25 = 5 * 5 25=55,5 可以分解为 ( 2 + i ) ∗ ( 2 − i ) (2 + i) * (2-i) (2+i)(2i),对 z z z 的每一个 p p p 进行分解得到 k k k 对互为共轭复数的高斯整数,将其分成两部分,每一对共轭复数留一个在左边,另一个留在右边,最后左边的高斯整数相乘得到的高斯整数和右边高斯整数相乘得到的高斯整数互为共轭复数,并且它们的乘积 = z = z =z

高斯整数还有4种变化: ( a + b i ) (a + bi) (a+bi) 可以乘上 1 , − 1 , i , − i 1,-1,i,-i 1,1,i,i,相当于旋转90°,一个圆上的高斯整数可以通过这个变化得到4个不同的高斯整数。

那么圆上的整点数 就是 左边高斯整数的组合数 再乘上 4,注意到这是一个可重集合。如何计算这个可重集合的组合数?
可以发现不同质因子之间的贡献独立,可以分别计算每一个质因子的组合数,最后乘起来即可。
显然 p k p^k pk ( k + 1 ) (k + 1) (k+1)种组合,枚举有几个 ( a + b i ) (a+bi) (a+bi)在左边即可。

如果 p p p 4 ∗ n + 3 4*n + 3 4n+3 的质数怎么办: 因为 4 ∗ n + 3 4 * n + 3 4n+3 型的质数是高斯质数,不可再分解,也就不存在共轭复数,那么必须要偶数次幂才能使得两边最后的乘积仍是共轭复数,且只有一种组合方式,若为奇数次幂,则不存在整点。

特殊质数 2: 前面并没有考虑 2,它既不是 4 n + 1 4n + 1 4n+1 也不是 4 n + 3 4n + 3 4n+3,但 2 可以分解为 ( 1 + i ) ∗ ( 1 − i ) (1 + i) *(1 - i) (1+i)(1i),特殊的是这两个复数 乘上 i i i 可以得到它的共轭复数,因此交换位置顺序相当于乘上 i,这和上面的操作重复,2 这个质因子对最后的答案没有贡献。

这个答案式子还可以表示成:

( h ( 1 ) + h ( p 1 1 ) + h ( p 1 2 ) + . . . h ( p 1 ) k 1 ) (h(1) + h(p_1^1) + h(p_1^2) + ...h(p_1)^{k_1}) (h(1)+h(p11)+h(p12)+...h(p1)k1)
∗ ( h ( 1 ) + h ( p 2 1 ) + h ( p 2 2 ) + . . . h ( p 2 ) k 2 ) *(h(1) + h(p_2^1) + h(p_2^2) + ...h(p_2)^{k_2}) (h(1)+h(p21)+h(p22)+...h(p2)k2)

证明:
p p p 4 n + 1 4n + 1 4n+1 型整数时,和等于 k + 1 k + 1 k+1
p p p 4 n + 3 4n + 3 4n+3 型整数时, h ( x ) h(x) h(x) 序列是 1 , − 1 , 1 , − 1.. 1,-1,1,-1.. 1,1,1,1.. 交替,奇数次项其和值为0,最后的答案为0,偶数次项其和值为1,没有影响。
p p p 2 2 2 时, h ( x ) = 0 h(x) = 0 h(x)=0,对最后的答案没有影响

更一般的,将这个式子展开,就得到 a n s = h ( a 1 ) + h ( a 2 ) + h ( a 3 ) + . . . + h ( a k ) , a k ans = h(a_1) + h(a_2) + h(a_3) + ... + h(a_k),a_k ans=h(a1)+h(a2)+h(a3)+...+h(ak)ak x x x 的因子,每个因子恰好出现一次。


对于这题,由于输入的是 r r r,要对 r 2 r^2 r2 进行质因子分解,利用 h ( x ) h(x) h(x) 采用第一种算式,对 r r r 进行质因子分解,得到的幂次 乘 2


代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,res = 0,cnt = 0;
int main() {
	scanf("%lld",&n);
	res = 1;
	for (int i = 2; 1ll * i * i <= n; i++) {
		if (n % i == 0) {
			cnt = 0;
			while (n % i == 0) {
				cnt++;
				n /= i;
			}
			cnt *= 2;
			if (i % 4 == 1) {
				res *= (cnt + 1);
			} else {
				res *= (cnt % 2 == 0);
			}
		}
	}
	if (n > 1 && n % 4 == 1) res *= 3;
	printf("%lld\n",4 * res);
	return 0;
} 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值