• 洛谷P2508 [HAOI2008]圆上的整点


    洛谷P2508 [HAOI2008]圆上的整点

    给定 \(r\),求圆 \(x^2+y^2=r^2\) 经过的整点个数。

    \(r\le 2\times10^9.\)

    首先推荐一下 3b1b 的视频:隐藏在素数规律中的π

    下面是我自己口胡的文字题解。可能写得很拉,有时间还是建议看视频。

    题解

    \(x^2+y^2=r^2\) 可以写成 \((x+yi)(x-yi)=r^2\)
    于是我们可以考虑如何把 \(R=r^2\) 拆成两个共轭复数 \(z,z'\) 的乘积。

    \(R\) 在实数域上分解质因数:
    \(r=\prod p_i^{k_i}\),则 \(R=\prod p_i^{2k_i}\)

    然后计算每个质因子 \(p\) 的贡献。

    \(p\) 在复数域上可能被继续分解为 \(p=(a+bi)(a-bi)\),即 \(p=a^2+b^2\)
    我们给出一条引理:

    费马二平方和定理
    一个奇素数 \(p\) 能被写成两个整数的平方和,当且仅当 \(p\equiv 1\pmod 4\)

    证明放在最后。接下来考虑原问题。
    将每个质因子 \(p_i\) 以某种方式分配到 \(z,z'\) 中,并维护 \(z,z'\) 始终为共轭复数。

    • \(p_i=2\)
      这个比较特殊,我们暂时不管它。

    • \(p_i\equiv 3\pmod 4\)
      根据引理,\(p_i\) 无法被继续分解。
      \(p_i\) 共出现 \(2k_i\) 次,唯一的分配方案是 \(z,z'\) 各分一半。对总方案数无影响。

    • \(p_i\equiv 1\pmod 4\)
      根据引理,\(p_i\) 可以被分解为 \((a+bi)(a-bi)\)。(注意区分虚数单位 \(i\) 和下标 \(i\)
      不妨考虑 \(z\),它被分配到 \(a+bi,a-bi\)\(2k_i\) 个,其中 \(a+bi\) 可以是 \(0\sim 2k_i\) 个,共 \(2k_i+1\) 种方案。

    每个有序数对 \((z,z')\) 对应了 4 个整点,分别是 \(z,iz,-z,-iz\)
    可以认为是将 \(z\) 绕原点分别旋转 \(0^{\circ},90^{\circ},180^{\circ},270^{\circ}\)
    因此要将前面计算出的方案数再乘以 4。

    最后来讨论 \(p_i=2\) 的情况。
    \(2=(1+i)(1-i)\),似乎可以对方案数产生影响。
    但是 \(1+i=(1-i)\cdot i\),也就是说,两者本质上只是转 \(90^{\circ}\) 的差别而已。
    这已经被包括在了将方案数乘以 4 的操作中,因此质因子 \(2\) 不再产生影响。

    至此,我们可以写出答案的表达式:

    \(r=\prod p_i^{k_i}\),则

    \[ans=4\prod_{p_i\%4=1}(2k_i+1) \]

    直接分解质因数计算即可。时间复杂度 \(O(\sqrt r)\)

    #include<stdio.h>
    int r,s=1,t;
    signed main() {
        scanf("%d",&r),r>>=__builtin_ctz(r); // 排除质因子 2
        for (int i=3; i*i<=r; i+=2)
            if (r%i==0) {
                while (r%i==0) r/=i,++t;
                (i&3)==1&&(s*=(t<<1|1)),t=0;
            }
        r>1&&(r&3)==1&&(s*=3);
        printf("%d\n",s<<2);
        return 0;
    }
    

    引理的证明

    首先我们证明 \(p\equiv 3\pmod 4\) 时,\(p\) 不能写成两个平方数的和。
    平方数模 4 得 0 或 1,则两个平方数的和模 4 只能得到 0,1,2,不可能等于 \(p\)

    接下来证明:对任意 \(p\equiv 1\pmod 4\)\(p\) 一定可以写成两个平方数的和。

    定义 \(S=\{(x,y,z)\in\mathbf N^3:x^2+4yz=p\}\)。显然 \(S\) 是有限集。
    考虑如下两个映射:

    \[\begin{aligned} (x,y,z)&\mapsto(x,z,y)\\ (x,y,z)&\mapsto\begin{cases} (x+2z,z,y-x-z)&{\rm if}~x<y-z\\ (2y-x,y,x-y+z)&{\rm if}~y-z<x<2y\\ (x-2y,x-y+z,y)&{\rm if}~x>2y \end{cases}\end{aligned}\]

    验证可知:
    它们都是 \(S\) 到本身的映射。
    它们都是对合。(映射两次得到自身)

    后者只有一个不动点。
    \(x+2z,x-2y\) 都不可能等于 \(x\),只有 \(2y-x=x\),即 \(x=y\) 时可能得到不动点。
    此时 \(p=x^2+4xz=x(x+4z)\),而 \(p\) 是质数,可知 \((x,y,z)=(1,1,\frac{p-1}4)\)。这就是唯一的不动点。

    所以 \(S\) 中元素个数为奇数。
    则前者必然也至少有一个不动点。(否则 \(S\) 中元素能两两配对,矛盾)
    这个不动点满足 \(p=x^2+4yz=x^2+(2y)^2\)。因此 \(p\) 一定可以写成两个平方数的和,结论得证。

    看完证明之后感觉完全想不来。只能说是仅供欣赏。

  • 相关阅读:
    Kudu-Impala集成特性
    [转]IIS的各种身份验证详细测试
    [转]The NTLM Authentication Protocol and Security Support Provider
    [转]WxEmojiView
    [转]Redis 数据类型
    [转]a-mongodb-tutorial-using-c-and-asp-net-mvc
    [转]MongoDB 概念解析
    [转]flash.net.Socket
    [转]emailjs-smtp-client
    [转]jquerUI Dialog中隐藏标题栏的关闭"X"按钮
  • 原文地址:https://www.cnblogs.com/REKonib/p/16217181.html
Copyright © 2020-2023  润新知