• P2508 [HAOI2008]圆上的整点


    更好的阅读体验

    题意:求半径为(r)的圆上有多少个整点,即求(x^2+y^2=r^2)有多少组整数解。

    我们考虑把(r^2=x^2+y^2)变形,得到(r^2=x^2-(-y^2)=(x+yi)(x-yi))

    所以我们就需要考虑通过分解(r^2)可以得到多少组不同的((x+yi)(x-yi))

    image-20201110171118981

    我们考虑如果有若干对共轭复数分别放在两边,最后得到的也是一对共轭复数,相乘就可以得到整数,我们希望这个整数是(r)

    那么就考虑如何求并分配这若干对共轭复数。

    费马平方和定理:奇素数 p 可以表示为两个正整数的平方和,当且仅当 p 是 4 k+1 型的。并且在不考虑两个正整数顺序的情况下,这个表示方法唯一。

    引入一个概念:高斯素数,即3,7这样形似4 n+3的素数,他们一定不能被分成((x+yi)(x-yi))的形式。

    否则,如果是形似4 n+1的素数,一定能被分成((x+yi)(x-yi))的形式。

    那么是否还忽略了某个素数呢?没错,2要特殊考虑,虽然它能被分成(1^2+1^2=(1+i)(1-i)),但特殊的是它所分解出的这两个高斯整数的夹角还刚好是90度,这个要在计算答案的时候特殊考虑一下。

    根据整数的惟一分解定理,我们可以让(r=p_1^{r_1}*p_2^{r_2}*...*p_k^{r_k})。考虑每个质因子对答案的影响。

    如果这个因子不是高斯素数,也就是它能被分解成((x+yi)(x-yi)),假设它的幂次是(m),那么我们可以得到(m)(z:(a+bi))(overline z:(a-bi)),考虑怎么分配。我们可以在左边分配([0,m])(z),右边分配剩下的(z),其他的就填(overline z)。这样它对答案的贡献就是(m+1)

    如果这个因子是高斯因数,也就是它不能被分解成((x+yi)(x-yi)),但是我们又一定要最后得到的等式两边共轭,所以只有当它的幂次(m)是偶数的时候,才能平均的分配到两边,否则就无解。

    当然,我们也可以把((x+yi),(x-yi))乘上(-1,i,-i)得到新的分解((-x-yi),(-x+yi),(-y+xi),(y+xi),(y-xi),(-y-xi)),所以我们还要把最后的答案乘上4.

    image-20201110172932198

    等等,是不是忘了什么?素数2还没有在我们讨论的范围中。它可以分为((1+i)(1-i)),我们还是选择放到两边,但是我们对它分解得到的两个共轭复数来乘上(-1,i,-i),得到的分解是((-1-i),(-1+i),(-1+i),(1+i),(1-i),(-1-i)),我们可以发现这样会得到重复的复数。

    不妨在几何中理解一下。

    上面的乘上(-1,i,-i)其实就是把((a+bi),(a-bi))两个点旋转起来,但是当这两个点的夹角是90度的时候,这旋转不能得到新的解,所以2对答案没有影响。

    所以最后的答案就是,将(r^2)进行质因数分解,一个高斯素数(p^m)若m是奇数,答案为0,否则不会对答案造成影响,一个非高斯素数(p^m)对答案的贡献是(m+1),2忽略不计。

    但是由于(r^2)里的每一个质数的指数一定是偶数,所以答案不会为0。其他的就没有问题了。

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    inline int read(){
       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<<1)+(x<<3)+(ch^48);ch=getchar();}
       return x*f;
    }
    int ans(int n){
    	int res=1;
    	for(int i=2;i*i<=n;i++){
    		if(n%i==0){
    			int cnt=0;
    			while(n%i==0)n/=i,cnt++;
    			if(i%4==1)res*=(cnt<<1|1); 
    		}
    	}
    	if(n!=1&&n%4==1)res*=(2+1);
    	return res<<2;
    }
    signed main(){
    	int n;
    	cin>>n;
    	cout<<ans(n)<<endl; 
    	return 0;
    }
    
  • 相关阅读:
    【论文阅读-Embedding】《GloVe: Global Vectors for Word Representation》
    机器学习的问题总结
    预算平滑
    ML基础番外篇-距离度量
    vim配置使用
    强化学习 Note
    强化学习(David Silver)9:探索与利用
    强化学习(David Silver)8:集成学习和计划
    强化学习(David Silver)7:策略梯度算法
    数学基础01-最优化(梯度下降法、牛顿法、拟牛顿法等)
  • 原文地址:https://www.cnblogs.com/moyujiang/p/14019680.html
Copyright © 2020-2023  润新知