【模板】数论

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int gcd(int x,int y){
    return x==0?y:gcd(y%x,x);
}
int n,m;
int main(){
    scanf("%d%d",&n,&m);
    cout<<gcd(n,m);
}
欧几里得
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,a,b;
void ex_gcd(int a,int b,int &x,int &y,int &d){
    if(!b){ d=a;x=1;y=0; }
    else{
        ex_gcd(b,a%b,y,x,d);
        y-=x*(a/b);
    }
}
int main(){
    scanf("%d%d",&a,&b);
    int x,y,d;
    ex_gcd(a,b,x,y,d);
    if(d==1)    cout<<(x%b+b)%b;
    else cout<<"-1";
}
拓展欧几里得
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 10000100
using namespace std;
int n,m,tot;
bool yes[MAXN];
int prime[1000000];
void pre(){
    memset(yes,true,sizeof(yes));
    yes[1]=false;
    for(int i=2;i<=n;i++){
        if(yes[i])    prime[++tot]=i;
        for(int j=1;i*prime[j]<=n;j++){
            yes[i*prime[j]]=false;
            if(i%prime[j]==0)    break;    
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    pre();
    cout<<tot;
    for(int i=1;i<=m;i++){
        int x;
        scanf("%d",&x);
        if(yes[x])    cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
}
欧拉筛法

逆元:http://www.cnblogs.com/cangT-Tlan/p/7794256.html

卢卡斯定理:http://www.cnblogs.com/cangT-Tlan/p/7793850.html

#include<cstdio>
#include<iostream>
using namespace std;
int n,a[11],b[11];
long long gcd(int x,int y){
    return x==0?y:gcd(y%x,x);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)    scanf("%d%d",&a[i],&b[i]);
    long long ans=b[1];
    long long lcm=a[1];
    for(int i=2;i<=n;i++){
        while(ans%a[i]!=b[i])    ans+=lcm;
        long long GCD=gcd(lcm,(long long)a[i]);
        lcm=lcm/GCD*(long long)a[i];
    }
    cout<<ans;
}
大数翻倍法(中国剩余定理)
#include<cstdio>
#include<iostream>
using namespace std;
long long n,ans;
int main(){
    while(1){
        scanf("%lld",&n);
        if(!n)    break;
        ans=n;
        for(long long i=2;i<=n;i++)
            if(n%i==0){
                while(n%i==0) n/=i;
                ans=ans/i*(i-1);
             }
        printf("%lld\n",ans);
    }
}
欧拉函数 O(n)
#include<cstdio>
#include<iostream>
using namespace std;
long long n,ans;
int main(){
    while(1){
        scanf("%lld",&n);
        if(!n)    break;
        ans=n;
        for(long long i=2;i*i<=n;i++)
            if(n%i==0){
                while(n%i==0) n/=i;
                ans=ans/i*(i-1);
             }
        if(n>1) ans=ans/n*(n-1);
        printf("%lld\n",ans);
    }
}
欧拉函数 O(sqrt(n))
#include<cstdio>
#include<iostream>
using namespace std;
long long n,ans;
int main(){    
    while(1){
        scanf("%lld",&n);
        if(!n) return 0;
        ans=n;
        if(n%2==0){
            while(n%2==0) n/=2;
            ans=ans/2;
        }
        for(long long i=3;i*i<=n;i+=2)
            if(n%i==0){
                while(n%i==0)    n/=i;
                ans=ans/i*(i-1);
            }
        if(n>1) ans=ans/n*(n-1);
        printf("%lld\n",ans);
    }
}
欧拉函数 O(sqrt(n)/2)

 

posted @ 2017-11-06 19:18  一蓑烟雨任生平  阅读(224)  评论(0编辑  收藏  举报