• 数论小专题总结


    (主要是各基本知识点的例题,查缺补漏,希望以后比赛不要有本来应该掌握的知识点,却不知道的情况)

    1、一元线性同余方程组的一般性解法(拓展gcd、剩余定理)

     1 /*poj2891*解一次线性同余方程组/
     2 /x%a[i]==r[i]*/
     3 /*通解*/
     4 #include<iostream>
     5 #include<string.h>
     6 #include<stdio.h>
     7 #define maxn  10000+5
     8 #define LL long long
     9 using namespace std;
    10 LL r[maxn],m[maxn];
    11 
    12 void Ex_gcd(LL a,LL b,LL &d,LL &x,LL &y){
    13     if (!b){
    14         x=1;y=0;d=a;
    15     }else{
    16         Ex_gcd(b,a%b,d,y,x);
    17         y=y-x*(a/b);
    18     }
    19 }
    20 LL Ex_crt(LL N){
    21     LL M=m[1],R=r[1],x,y,d;
    22     for(int i=2;i<=N;i++){
    23         Ex_gcd(M,m[i],d,x,y);
    24         if ((r[i]-R)%d!=0) return -1;//无解
    25         x=(r[i]-R)/d*x%(m[i]/d);
    26         R=R+x*M;
    27         M=M/d*m[i];
    28         R%=M;
    29     }
    30     if (R<0) R+=M;
    31     return R;
    32 }
    33 int n;
    34 int main(){
    35     while(~scanf("%I64d",&n)){
    36         for(int i=1;i<=n;i++){
    37             scanf("%I64d%I64d",&m[i],&r[i]);
    38         }
    39         LL ans=Ex_crt(n);
    40         printf("%I64d
    ",ans);
    41     }
    42     return 0;
    43 }
    View Code
     1 /*hdu3579解一次线性同余方程组/
     2 /x%a[i]==r[i]*/
     3 /*通解*/
     4 /*注意,题目要求的是最小“正”整数解,如果同余方程组的解为0,则解是A[i]的最小公倍数*/
     5 #include<iostream>
     6 #include<string.h>
     7 #include<algorithm>
     8 #include<stdlib.h>
     9 #include<stdio.h>
    10 #define maxn  100+5
    11 #define typed long long
    12 using namespace std;
    13 typed r[maxn],m[maxn];
    14 
    15 typed gcd(typed a,typed b){
    16     return b==0?a:gcd(b,a%b);
    17 }
    18 void Ex_gcd(typed a,typed b,typed &d,typed &x,typed &y){
    19     if (!b){
    20         x=1;y=0;d=a;
    21     }else{
    22         Ex_gcd(b,a%b,d,y,x);
    23         y=y-x*(a/b);
    24     }
    25 }
    26 typed Ex_crt(typed N){
    27     typed M=m[1],R=r[1],x,y,d;
    28     for(int i=2;i<=N;i++){
    29         Ex_gcd(M,m[i],d,x,y);
    30         if ((r[i]-R)%d!=0) return -1;//无解
    31         x=(r[i]-R)/d*x%(m[i]/d);
    32         R=R+x*M;
    33         M=M/d*m[i];
    34         R%=M;
    35     }
    36     if (R<0) R+=M;
    37     return R;
    38 }
    39 typed n,T;
    40 typed lcm(){
    41     if (n==1) return m[1];
    42     sort(m+1,m+n+1);
    43     typed GCD=gcd(m[2],m[1]);
    44     for(int i=3;i<=n;i++)
    45     GCD=gcd(m[i],GCD);
    46     typed ans=1;
    47     for(int i=1;i<=n;i++) ans=ans*m[i]/GCD;
    48     return ans;
    49 }
    50 int main(){
    51     cin>>T;
    52     for(int cas=1;cas<=T;cas++){
    53         scanf("%I64d",&n);
    54         for(int i=1;i<=n;i++){
    55             scanf("%I64d",&m[i]);
    56         }
    57         for(int i=1;i<=n;i++){
    58             scanf("%I64d",&r[i]);
    59         }
    60         printf("Case %d: ",cas);
    61         typed ans=Ex_crt(n);
    62         if (ans==0) ans=lcm();
    63         printf("%lld
    ",ans);
    64     }
    65     return 0;
    66 }
    View Code

    2、高次同余方程babystep算法

      1 /*HDU - 2815
      2 题意比较有趣,
      3 但化成数学模型,
      4 就是求K^D=N mod P;
      5 K,P,N已知,求D的最小整数解。
      6 有个小坑,N<P 才可
      7 所以就是个解高次同余方程的题目
      8 */
      9 #include<cmath>
     10 #include<iostream>
     11 #include<string.h>
     12 #include<stdio.h>
     13 #define maxn  65535
     14 #define LL long long
     15 using namespace std;
     16 struct hash{
     17     int a,b,next;
     18 }Hash[maxn*2];
     19 int flg[maxn+70];
     20 int top,idx;
     21 void ins(int a,int b){
     22     int k=b&maxn;
     23     if (flg[k]!=idx){
     24         flg[k]=idx;
     25         Hash[k].next=-1;
     26         Hash[k].a=a;
     27         Hash[k].b=b;
     28         return ;
     29     }
     30     while(Hash[k].next!=-1){
     31         if (Hash[k].b==b) return ;
     32         k=Hash[k].next;
     33     }
     34     Hash[k].next=++top;
     35     Hash[top].next=-1;
     36     Hash[top].a=a;
     37     Hash[top].b=b;
     38 }
     39 
     40 int find(int  b){
     41     int k=b&maxn;
     42     if (flg[k]!=idx) return -1;
     43     while(k!=-1){
     44         if (Hash[k].b==b)
     45             return Hash[k].a;
     46         k=Hash[k].next;
     47     }
     48     return -1;
     49 }
     50 int gcd(int a,int b){
     51     return b==0?a:gcd(b,a%b);
     52 }
     53 int ext_gcd(int a,int b,int &x,int &y){
     54     int t,ret;
     55     if (!b) {
     56         x=1,y=0;return a;
     57     }
     58     else{
     59         ret=ext_gcd(b,a%b,x,y);
     60         t=x;x=y;y=t-a/b*y;
     61         return ret;
     62     }
     63 
     64 }
     65 int Inval(int a,int b,int n){
     66     int x,y,e;
     67     ext_gcd(a,n,x,y);
     68     e=(long long) x*b%n;
     69     return e<0?e+n:e;
     70 }
     71 int pow_mod(long long a,int b,int c){
     72     long long ret=1%c;a=a%c;
     73     while(b){
     74         if (b&1)
     75         ret=ret*a%c;
     76         a=a*a%c;
     77         b=b>>1;
     78     }
     79     return ret;
     80 }
     81 int BabyStep(int A,int B,int C){
     82     top=maxn;++idx;
     83     long long buf=1%C,D=buf,K;
     84     int i,d=0,tmp;
     85     for(i=0;i<=100;buf=buf*A%C,i++)
     86         if (buf==B) return i;
     87 
     88     while((tmp=gcd(A,C))!=1){
     89         if (B%tmp) return -1;
     90         ++d;
     91         C=C/tmp;
     92         B=B/tmp;
     93         D=D*A/tmp%C;
     94     }
     95     int M=(int)ceil(sqrt((double)C));
     96     for( buf=1%C,i=0;i<=M;buf=buf*A%C,i++) ins(i,buf);
     97     for( i=0,K=pow_mod((long long)A,M,C);i<=M;D=D*K%C,i++){
     98         tmp=Inval((int)D,B,C);int w;
     99         if (tmp>=0 && (w=find(tmp))!=-1)
    100         return i*M+w+d;
    101     }
    102     return -1;
    103 }
    104 LL K,P,N;
    105 int main(){
    106     while(cin>>K>>P>>N){
    107         if (N>P){
    108             cout<<"Orz,I can’t find D!"<<endl;
    109             continue;
    110         }
    111         N=N%P;
    112         int tmp=BabyStep(K,N,P);//参数是底数,被除数,除数
    113         if (tmp<0)
    114             cout<<"Orz,I can’t find D!"<<endl;
    115         else
    116             printf("%d
    ",tmp);
    117     }
    118     return 0;
    119 }
    View Code
      1 /*Poj 3243
      2 就是求K^X=N mod P;
      3 K,P,N已知,求X的最小整数解
      4 解高次同余方程的题目
      5 */
      6 #include<cmath>
      7 #include<iostream>
      8 #include<string.h>
      9 #include<stdio.h>
     10 #define maxn  65535
     11 #define LL long long
     12 using namespace std;
     13 struct hash{
     14     int a,b,next;
     15 }Hash[maxn*2];
     16 int flg[maxn+70];
     17 int top,idx;
     18 void ins(int a,int b){
     19     int k=b&maxn;
     20     if (flg[k]!=idx){
     21         flg[k]=idx;
     22         Hash[k].next=-1;
     23         Hash[k].a=a;
     24         Hash[k].b=b;
     25         return ;
     26     }
     27     while(Hash[k].next!=-1){
     28         if (Hash[k].b==b) return ;
     29         k=Hash[k].next;
     30     }
     31     Hash[k].next=++top;
     32     Hash[top].next=-1;
     33     Hash[top].a=a;
     34     Hash[top].b=b;
     35 }
     36 
     37 int find(int  b){
     38     int k=b&maxn;
     39     if (flg[k]!=idx) return -1;
     40     while(k!=-1){
     41         if (Hash[k].b==b)
     42             return Hash[k].a;
     43         k=Hash[k].next;
     44     }
     45     return -1;
     46 }
     47 int gcd(int a,int b){
     48     return b==0?a:gcd(b,a%b);
     49 }
     50 int ext_gcd(int a,int b,int &x,int &y){
     51     int t,ret;
     52     if (!b) {
     53         x=1,y=0;return a;
     54     }
     55     else{
     56         ret=ext_gcd(b,a%b,x,y);
     57         t=x;x=y;y=t-a/b*y;
     58         return ret;
     59     }
     60 
     61 }
     62 int Inval(int a,int b,int n){
     63     int x,y,e;
     64     ext_gcd(a,n,x,y);
     65     e=(long long) x*b%n;
     66     return e<0?e+n:e;
     67 }
     68 int pow_mod(long long a,int b,int c){
     69     long long ret=1%c;a=a%c;
     70     while(b){
     71         if (b&1)
     72         ret=ret*a%c;
     73         a=a*a%c;
     74         b=b>>1;
     75     }
     76     return ret;
     77 }
     78 int BabyStep(int A,int B,int C){//A:底数,B:被除数,C除数
     79     top=maxn;++idx;
     80     long long buf=1%C,D=buf,K;
     81     int i,d=0,tmp;
     82     for(i=0;i<=100;buf=buf*A%C,i++)
     83         if (buf==B) return i;
     84 
     85     while((tmp=gcd(A,C))!=1){
     86         if (B%tmp) return -1;
     87         ++d;
     88         C=C/tmp;
     89         B=B/tmp;
     90         D=D*A/tmp%C;
     91     }
     92     int M=(int)ceil(sqrt((double)C));
     93     for( buf=1%C,i=0;i<=M;buf=buf*A%C,i++) ins(i,buf);
     94     for( i=0,K=pow_mod((long long)A,M,C);i<=M;D=D*K%C,i++){
     95         tmp=Inval((int)D,B,C);int w;
     96         if (tmp>=0 && (w=find(tmp))!=-1)
     97         return i*M+w+d;
     98     }
     99     return -1;
    100 }
    101 LL K,P,N;
    102 //K^X=N mod P;
    103 int main(){
    104     while(cin>>K>>P>>N){
    105         if (K==0 && P==0 && N==0) break;
    106         int ans=BabyStep(K,N,P);
    107         if (ans==-1) puts("No Solution");else cout<<ans<<endl;
    108     }
    109     return 0;
    110 }
    View Code

    3、中国剩余定理

     1 /*Poj1006中国剩余定理:
     2 给定n组数对,使得:
     3 A[i]==X(mod M[i])
     4 
     5 剩余定理描述:
     6 设m1,m2,…,mk是两两互素的正整数,则同余
     7 方程组
     8           x=b1 mod m1
     9           x=b2 mod m2
    10 11           x=bk mod mk
    12     有唯一解:x=(b1T1M1+…+bkTkMk  )mod M
    13     其中,M=m1×m2×…mk(即lcm)
    14            Mi=M/mi
    15            Ti=Mi(-1) mod mi 乘法逆元
    16 
    17 
    18 pps:
    19  应用中国剩余定理,可以简化一些复杂的运算。
    20  如计算  47317 mod 713
    21      解:因为713=2331,令x=47317,
    22         则计算x mod 713等价于求解同余方程:
    23             x=47317 mod 23=1317 mod 23
    24             x=47317 mod 31=817 mod 31
    25    即: x=6 mod 23
    26          x=2 mod 31
    27    根据中国剩余定理可得解x=374(mod 713)
    28    因此:47317 mod 713=374(mod 713)
    29 
    30 */
    31 /*对于这道题啊,因为数据量太小,手动计算即可,
    32 M=23*28*33=21252
    33 ans=(b1*924*6+b2*759*19+b3*644*2-d + M)% M;//最小正整数解
    34 */
    35 #include<iostream>
    36 #include<string>
    37 #include<algorithm>
    38 #include<cstdio>
    39 #include<cstring>
    40 #include<cmath>
    41 #include<queue>
    42 #include<map>
    43 #include<stack>
    44 #include<set>
    45 #include<cstdlib>
    46 
    47 using namespace std;
    48 
    49 int d,b1,b2,b3;
    50 int cas=0;
    51 int main(){
    52     while(cin>>b1>>b2>>b3>>d){
    53         if (d==-1 && b1==-1  && b2==-1 && b3==-1) break;
    54         cas++;
    55         int M=23*28*33;
    56         int ans=(b1*924*6+b2*759*19+b3*644*2-d + M)% M;
    57         if (ans==0) ans=M;//正整数解!
    58         printf("Case %d: the next triple peak occurs in %d days.
    ",cas,ans);
    59     }
    60     return 0;
    61 }
    View Code

     4、二元一次不定方程

     1 /*poj2142
     2 解二元一次不定方程
     3 题目描述:给定质量为a和b的砝码,不限天平左右可以放置砝码,称出一个c的质量的物品就可以了
     4 ax+by=d列出数学方程,x和y的正负表示放置的左右,现在要求
     5 |X|+|Y|尽量小,然后是|aX|+|BY|尽量小
     6 
     7 http://116.255.173.144/index.php?c=article&a=read&id=56659
     8 因为欧几里德扩展算法只能求ax + by = gcd(a, b);所以,先求a, b的最大公约数gcd_ab,对于ax + by = d,令a, b, d同除以gcd_ab,然后可求得(a/gcd_ab)x + (b/gcd_ab)y = 1的最小整数解,然后将求得的这组解乘以d/gcd_ab得x0, y0,就是ax + by = d一组解,由数论知识得ax + by = d的所有解为: x = x0 - bt, y = y0 + at(t为参数),那么,要使|x|+|y|最小,可令x = 0求得一组解,再令y = 0求得一组解,两组比较取较小者就好。
     9 
    10 一般方法,拓展欧几里得解出一组特解(x0,y0)
    11 x0=x0*(c/d);
    12 y0=y0*(c/d);
    13 令d=gcd(a,b),a0=a/d,b0=b/d;
    14 则通解是x=x0+a0t,y=y0-b0t(t不所谓正负)
    15 
    16 这道题,一般都是分析函数的单调性了(需要中学数学知识):
    17 假设a0>b0,当|x|+|y|最小时,有-b0<y<b0(可以画出函数图像)
    18 尝试几组解即可
    19 //http://hi.baidu.com/lydrainbowcat/item/07913682130d07dcd1f8cd83
    20 */
    21 #include <iostream>
    22 #include <string.h>
    23 #include <stdio.h>
    24 #include <stdlib.h>
    25 #include <cmath>
    26 #define LL long long
    27 using namespace std;
    28 
    29 LL abs(LL x){
    30     if (x<0) return -x;else return x;
    31 }
    32 void Ex_gcd(LL a,LL b,LL &x,LL &y,LL &d){//d==gcd(a,b)
    33     if (b==0) {
    34         d=a;x=1;y=0;
    35     }else{
    36         Ex_gcd(b,a%b,y,x,d);y-=x*(a/b);
    37     }
    38 }
    39 int main(){
    40     LL a,b,c,d,x0,y0;
    41     while(cin>>a>>b>>c){
    42         if (a==0 && b==0 && c==0) break;
    43         LL chan=0;
    44         if (a<b){
    45             chan=1;
    46             swap(a,b);
    47         }
    48         Ex_gcd(a,b,x0,y0,d);
    49         x0=x0*c/d;
    50         y0=y0*c/d;
    51         //令y0-b0t==0解出一个特解t0,然后在t0周围测试
    52         LL t0=(y0)*d/a;
    53         LL a0=a/d,b0=b/d;
    54         LL max_xy=999999999;
    55         LL ansx,ansy;
    56         LL max_xayb;
    57         for(LL t=t0-10;t<=t0+10;t++){
    58             LL nx=x0+b0*t;
    59             LL ny=y0-a0*t;
    60             if(max_xy>abs(nx)+abs(ny)){
    61                 max_xy=abs(nx)+abs(ny);
    62                 max_xayb=abs(nx*a)+abs(ny*b);//开始时忘记更新
    63                 ansx=nx;ansy=ny;
    64             }
    65              else if (max_xy==abs(nx)+abs(ny)){
    66                 if (max_xayb>abs(nx*a)+abs(ny*b)){
    67                     max_xayb=abs(nx*a)+abs(ny*b);
    68                     ansx=nx;ansy=ny;
    69                 }
    70             }
    71         }
    72         if (chan) swap(ansx,ansy);
    73         cout<<abs(ansx)<<" "<<abs(ansy)<<endl;
    74     }
    75     return 0;
    76 }
    View Code

    5、n元一次不定方程

     1 /*poj1091跳蚤
     2 很经典的一道题,隐藏在活泼的外表下的是,n元一次不定方程。= =
     3 还有,代数系统,容斥原理的应用 = =!
     4 
     5 题目描述:
     6 1、有一只跳蚤在一个横坐标上跳着,它有1+N张卡片,从大到小,最后一张上是M。每次可选择一张,按照上面的数字,卡片可以重复使用,随便向左还是向右跳。
     7 2、它的目标是跳到左边一个单位的位置
     8 
     9 分析:
    10 1、数学方程:设每张卡片的值是a1,a2.....an,M (1+n张)
    11 假设相应选择了xi次(正负代表左右)
    12 则 a1x1+a2x2+a3x3.....anxn+Mx(n+1)=1
    13 这个方程有解的充要条件是gcd(a1,a2,a3,....,M)==1
    14 2、现在问题转化成了[1,M]的范围内找出几个数(包括M),使它们的gcd等于1,问这种分组有多少?
    15 
    16 容斥原理
    17 1、因为必须包含M这个数,所以一组中的数一定没有公因数(来自M因式分解的因子)
    18 2、容斥:
    19 总排列数M^N-sigm(排除含p1的分组,含p2的....)+sigm(含p1*p2的...含pi*pi+1的)-sigm(p1p2p3.....)....
    20 3、举例:含p1公因子的分组数k=M/p1 是M范围内有因子p1的数的个数.选取其中的N张(有顺序,可重复),总共K^N
    21 4、表示:状态压缩,很久没用了啊
    22 
    23 这个博客不错:http://www.cnblogs.com/zhaoguanqin/archive/2012/02/25/2368058.html
    24 */
    25 #include <iostream>
    26 #include <string.h>
    27 #include <stdio.h>
    28 #include <stdlib.h>
    29 #include <cmath>
    30 #define maxn 3200
    31 #define LL long long
    32 using namespace std;
    33 bool flag[maxn];
    34 LL cnt;
    35 LL prim[maxn];
    36 LL dive[25];
    37 void prim_calc(){//素数打表
    38     cnt=0;
    39     memset(flag,0,sizeof(flag));
    40     for(LL i=2;i<maxn;i++){
    41         if (!flag[i]) {
    42             prim[cnt++]=i;
    43             flag[i]=true;
    44             for(LL j=2*i;j<maxn;j+=i) flag[j]=false;
    45         }
    46     }
    47 }
    48 LL count;
    49 LL divide(LL M){
    50     count = 0;
    51     for(LL i=0;i<cnt;i++){
    52         if (M%prim[i]==0){
    53             dive[count++]=prim[i];
    54             while(M%prim[i]==0) M=M/prim[i];
    55             if (M==1) break;
    56         }
    57     }
    58     if (M>1) dive[count++]=M;
    59 //    for(LL i=0;i<count;i++) cout<<dive[i]<<" ";cout<<endl;
    60     return count;
    61 }
    62 LL N,M;
    63 int main(){
    64     prim_calc();
    65     while(cin>>N>>M){
    66         LL dig=divide(M);//
    67         LL ans=pow(M,N);
    68         LL tmp,flag,i,j;
    69         for(i=1;i<(LL)(1<<dig);i++)//状态压缩
    70         {
    71             tmp=1,flag=0;
    72             for(j=0;j<dig;j++)
    73                 if(i&((LL)(1<<j)))//判断第几个因子目前被用到
    74                     flag++,tmp*=dive[j];
    75             if(flag&1)//容斥原理,奇加偶减
    76                 ans-=pow(M/tmp,N);
    77             else
    78                 ans+=pow(M/tmp,N);
    79         }
    80         cout<<ans<<endl;
    81     }
    82     return 0;
    83 }
    View Code

     6、二元二次不定方程(佩尔方程)

     1 /*HDU3292
     2 佩尔方程(二元二次方程)
     3 形如X^2-d*Y^2=1(d>1)
     4 如果d为不完全数,则有解:否则,无解。
     5 求解佩尔方程的两种方法
     6 1、暴力法(本题)
     7 2、连分数法(zoj3759:http://www.cnblogs.com/little-w/p/3588285.html 8 求佩尔方程的解(矩阵快速幂)
     9 |x[k]|=|x1 d*y1|^(k-1) |x1|
    10 |y[k]|=|y1 x1  |       |y1|
    11 思路:暴力或者连分数法求x1+矩阵快速幂
    12 */
    13 #include <iostream>
    14 #include <string.h>
    15 #include <stdio.h>
    16 #include <cmath>
    17 #define LL long long
    18 #define mod 8191
    19 using namespace std;
    20 
    21 int x,y,d,k;
    22 bool isquare(){
    23     int sq=sqrt(d+0.0);
    24     if (((int)sq*(int)sq)==d) return true;
    25     else return false;
    26 }
    27 void search(){
    28     y=1;
    29     while(1){
    30         x=(long long)sqrt(d*y*y+1);
    31         if (x*x-d*y*y==1)
    32            break;
    33         y++;
    34     }
    35 }
    36 struct Mat
    37 {
    38     LL mat[3][3];
    39 };
    40 Mat operator*(Mat a,Mat b)
    41 {
    42     Mat c;
    43     memset(c.mat,0,sizeof(c.mat));
    44     for (int i=0;i<2;i++)
    45         for (int j=0;j<2;j++)
    46             for (int k=0;k<2;k++)
    47                 if (a.mat[i][k] && b.mat[k][j])
    48                    c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod;
    49     return c;
    50 }
    51 Mat operator+(Mat a,Mat b)
    52 {
    53     Mat c;
    54     memset(c.mat,0,sizeof(c.mat));
    55     for (int i=0;i<2;i++)
    56         for (int j=0;j<2;j++)
    57             c.mat[i][j]=(a.mat[i][j]+b.mat[i][j])%mod;
    58     return c;
    59 }
    60 Mat E;
    61 void builtE()
    62 {
    63     memset(E.mat,0,sizeof(E.mat));
    64     for (int i=0;i<2;i++)
    65     {
    66         E.mat[i][i]=1;
    67     }
    68 }
    69 Mat operator^(Mat A,int x)
    70 {
    71     Mat c;
    72     builtE();
    73     c=E;
    74     for ( ; x; x>>=1)
    75     {
    76         if ( x & 1)
    77             c = c * A;
    78         A = A * A;
    79     }
    80     return c;
    81 }
    82 int main(){
    83     while(cin>>d>>k){
    84         if (isquare()) {
    85             printf("No answers can meet such conditions
    ");
    86             continue;
    87         }
    88         search();
    89         Mat A;
    90         A.mat[0][0]=x,A.mat[0][1]=d*y,A.mat[1][0]=y,A.mat[1][1]=x;
    91         A=A^(k-1);
    92         Mat B;
    93         B.mat[0][0]=x,B.mat[1][0]=y;
    94         B=A*B;
    95         cout<<B.mat[0][0]<<endl;
    96     }
    97     return 0;
    98 }
    View Code

     7、本原毕达哥拉斯三元组定理

     1 /*fzu1669
     2 毕达哥拉斯三元组的应用
     3 
     4 本原毕达哥拉斯定理:
     5 x=m^2-n^2;
     6 y=2mn;
     7 z=m^2+n^2;
     8 m>n,n奇数m偶数或者n偶数m奇数
     9 注意是本原,即(x,y,z)==1,可通过计算本原加上筛选求得一定范围内的所有(x,y,z)
    10 
    11 题意:
    12 a+b+c<=L,
    13 a,b是直角边,c是斜边
    14 给定L ,求满足上式的三角形的个数
    15 思路:通过上面的定理,枚举出m,n(需满足gcd(n,m)==1),找到本原,筛选可得解
    16 具体实现:假设m>n,则m<sqrt(L),再枚举比m小的n即可,因为L≤2000000,m<1000,单次最多不会超过500000左右
    17 */
    18 #include <iostream>
    19 #include <string.h>
    20 #include <stdio.h>
    21 #include <cmath>
    22 #define LL long long
    23 
    24 using namespace std;
    25 int L;
    26 int gcd(int a,int b){
    27     if (b==0) return a;
    28     else return gcd(b,a%b);
    29 }
    30 int main(){
    31     while(cin>>L){
    32         int up=(int)(sqrt(L+0.0));
    33         int ans=0;
    34         for(int m=1;m<=up;m++){
    35             for(int n=m-1;n>=1;n--){
    36                 if ((m+n)%2==0 || gcd(m,n)!=1) continue;
    37                 int x=m*m-n*n;
    38                 int y=2*n*m;
    39                 int z=m*m+n*n;
    40                 ans+=L/(x+y+z);
    41             }
    42         }
    43         cout<<ans<<endl;
    44     }
    45     return 0;
    46 }
    View Code

    8、欧拉函数的应用 POJ 3696

    {参考:http://blog.csdn.net/xieshimao/article/details/6689780}

    9、lucas定理 HDU3944

  • 相关阅读:
    C#拾遗(一、基本类型)
    JS正则表达式的test()方法检查汉字
    从程序员到项目经理(一)
    程序员基本素质要求
    似乎比较快
    Qt常用类
    QT 获取窗口 大小 信息
    QT 获取屏幕尺寸的法子
    Qt中 QString 和int, char等的“相互”转换
    qt 读取xml文件
  • 原文地址:https://www.cnblogs.com/little-w/p/3606994.html
Copyright © 2020-2023  润新知