bzoj1041

来源:互联网 发布:java中数组去重 编辑:程序博客网 时间:2024/06/06 00:37

参考链接:
http://www.cppblog.com/zxb/archive/2010/10/18/130330.html
http://blog.csdn.net/popoqqq/article/details/39895149

《初等数学》(潘承洞):
对于具有
x2+y2=z2
这种形式的式子来说,求它的本原解
(即x>0,y>0,z>0,(x,y,z)=1,但是可以得出(x,y)=1,(y,z)=1,(x,z)=1)
时具有以下性质:x和y不可能同时为奇数。所以求解的答案必然是x,y一个偶数,一个奇数,z是一个奇数,那么我们只要求出y为偶数时所有的可行本原解,即为所有的本原解。

当y是偶数时(设 y=2n):
(z+x)/2是整数,且(zx)/2是整数,
((z+x)/2,(zx)/2)|x((z+x)/2,(zx)/2)|z(只要把(z+x)/2(zx)/2相加减,就能得到这样的结论。)
又因为本原解中,(x.z)=1,所以((z+x)/2,(zx)/2)=1
又因为(z+x)/2>(zx)/2n2=((z+x)/2)((zx)/2),
所以(z+x)/2=r2(zx)/2=s2n=rs,
r>s>0,(r,s)=1,2(r+s)z=4p+1或者z=4p+3,把x化成类似的形式,在进行加减即可证明)
z=r2+ss,x=r2s2,y=2rs
易证,只要满足这种形式就满足 x2+y2=z2

按照题解中的转化方式,就可以用o(sqrt(n))的方法解决了,比o(n)的方法少多了。

(这次尝试用了不同的博客编辑器,发现这个挺好看的,只不过找不到表情)
(Something for nothing. -《龙族》)

2015.10.29:
宿舍连个暖宝宝的都不了电是个什么样的节奏?充会电,断会电,再充会,再断会,幸亏是大早晨,舍友都还在睡,不用电,否则他们不得揍死我吗?

#include<stdio.h>#include<string.h>#include<math.h>#include<iostream>using namespace std;#define N 100000int fanum[N];int facou;void getfactor(int n){    facou=0;    for(int i=1;i*i<=n;i++){        if(n%i==0){            fanum[facou++]=i;            if(i*i!=n){//这个应该放在if(n%i==0)这个判断里面,而不是外面                fanum[facou++]=n/i;            }        }    }    return;}int gcd(int a,int b){    int c;    while(b){        c=b;        b=a%b;        a=c;    }    return a;}int main(){    int n;    int ans;    while(scanf("%d",&n)!=EOF){        getfactor(n);        //printf("%d\n",n);        /*for(int i=0;i<facou;i++){            printf("%d ",fanum[i]);        }        printf("\n");*/        ans=0;        for(int i=0;i<facou;i++){            int tempz=fanum[i];            for(int i=1;i*i<=tempz;i++){//rs等于0的情况另算                int tempssq=tempz-i*i;                int temps=sqrt(tempssq);                if(temps>0&&i>temps&&temps*temps==tempssq&&gcd(temps,i)==1&&(i+temps)%2){                    ans++;                    //printf("%d %d %d\n",tempz,i,temps);                    if(i*i-temps*temps!=2*i*temps){//在解方程x^2+y^2=z^2时,xy互换没什么影响,但是这里影响点的个数,所以要判断如果xy不相同的话,要多加一个。                        ans++;                        //printf("%d %d\n",temps,i);                    }                }            }        }        ans=ans*4+4;        printf("%d\n",ans);        //break;//加不加break都能ac,这是为什么呢?    }    return 0;}
0 0