ACM数论模板(转)

博客汇总了多种算法相关知识及参考题目,包括最大公约数和最小公倍数、快速幂取模(Montgomery算法)、费马小定理等,还涉及找规律、循环递推、同余式、素数测试、筛选法等内容,并给出了对应HDU的题目链接。

转自:http://www.cnblogs.com/Lee-geeker/p/3372084.html

1.最大公约数和最小公倍数。

//模版
int gcd(int a, int b)
{
    if(a<b){int t=a;a=b;b=t;}
    return a%b==0?b:gcd(b,a%b);
}
int lcm(int a, int b)
{
    return a/gcd(a,b)*b;
}

参考题目:HDU1018 http://acm.hdu.edu.cn/showproblem.php?pid=1108

#include<iostream>

using namespace std;

int gcd(int a, int b){    if(a<b){int t=a;a=b;b=t;}    return a%b==0?b:gcd(b,a%b);}
int lcm(int a, int b){    return a/gcd(a,b)*b;}

int main()
{
    int a,b;
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        printf("%d\n",lcm(a,b));
    }
    return 0;
}

2.快速幂取模(Montgomery算法)

__int64 qpow(int a,int b,int r)//快速幂 
{
    __int64 ans=1,buff=a;
    while(b)
    {
        if(b&1)ans=(ans*buff)%r;
        buff=(buff*buff)%r;
        b>>=1;
    }
    return ans;
}

参考题目:HDU1395  http://acm.hdu.edu.cn/showproblem.php?pid=1395

#include<iostream>

using namespace std;

unsigned Montgomery(unsigned n,unsigned p,unsigned m)
{ //快速计算(n^e)%m的值
      unsigned k=1;
      n%=m;
     while(p!=1)
     {
         if(0!=(p&1))k=(k*n)%m;
         n=(n*n)%m;
         p>>=1;
    }
    return(n*k)%m;
}
int main()
{
    int n;
    int flag,i;
    while(scanf("%d",&n)!=EOF)
    {
        if(!(n&1)||n<=1)
            printf("2^? mod %d = 1\n",n);
        else
            for(i=1;;i++)
            {
                if(Montgomery(2,i,n) == 1)
                {
                    printf("2^%d mod %d = 1\n",i,n);
                    break;
                }
            }
    }
    return 0;
}

参考题目:HDU2035 http://acm.hdu.edu.cn/showproblem.php?pid=2035

#include<iostream>

using namespace std;

__int64 qpow(int a, int p, int r)
{
    int ans = 1;
    int buff = a;
    while(p)
    {
        if(p&1)    ans = (ans*buff)%r;
        buff = buff*buff%r;
        p>>=1;
    }
    return ans;
}

int main()
{
    int a,b;
    while(scanf("%d%d",&a,&b)!=EOF&&(a!=0&&b!=0))
    {
        printf("%d\n",qpow(a,b,1000));
    }
    return 0;
}
#include <iostream>
using namespace std;
int main()
{
    int a,b,ans;
    while(cin>>a>>b)
    {
        if(!a && !b)
            break;
        ans=0;
        a=a%1000;
        int tmp=a;
        while(b-->1)
        {
            a=(a*tmp)%1000;
        }
        cout<<a<<endl;
    }
    return 0;
}

3.费马小定理

费马小定理是数论中的一个重要定理,其内容为: 假如p是质数,且gcd(a,p)=1,那么 a^(p-1) ≡1(mod p)。即:假如p是质数,且a,p互质,那么a的(p-1)次方除以p的余数恒等于1。

4196 4704

 

4.找规律,循环问题,递推

1005 1021 2050 1719

 

5.同余式,中国剩余定理

3430 1573

 

6.米勒拉宾素数测试

__int64 qpow(int a, int b, int r)
{
    __int64 ans=1, buffer=a;
    while(b)
    {
        if(b&1) ans = ans*buffer%r;
        buffer = buffer*buffer%r;
        b>>=1;
    }
    return ans;
}
bool Miller_Rabbin(int n, int a)
{
    int r=0,s=n-1,j;
    if(!(n%a))
        return false;
    while(!(s&1))
    {
        s>>=1;
        r++;
    }
    __int64 k=qpow(a,s,n);
    if(k==1)
        return true;
    for(j=0;j<r;j++,k=k*k%n)
    {
        if(k==n-1)
                return true;        
    }
    return false;
}

bool IsPrime(int n)
{
    int tab[]={2,3,5,7,11};
    for(int i=0;i<5;i++)
    {
        if(n==tab[i])
            return true;
        if(!Miller_Rabbin(n,tab[i]))
            return false;    
    }
    return true;
}

参考题目:HDOJ2138 http://acm.hdu.edu.cn/showproblem.php?pid=2138

#include<iostream>


using namespace std;


__int64 qpow(int a, int b, int r)
{
    __int64 ans=1, buffer=a;
    while(b)
    {
        if(b&1) ans = ans*buffer%r;
        buffer = buffer*buffer%r;
        b>>=1;
    }
    return ans;
}
bool Miller_Rabbin(int n, int a)
{
    int r=0,s=n-1,j;
    if(!(n%a))
        return false;
    while(!(s&1))
    {
        s>>=1;
        r++;
    }
    __int64 k=qpow(a,s,n);
    if(k==1)
        return true;
    for(j=0;j<r;j++,k=k*k%n)
    {
        if(k==n-1)
                return true;        
    }
    return false;
}

bool IsPrime(int n)
{
    int tab[]={2,3,5,7,11,13};
    for(int i=0;i<6;i++)
    {
        if(n==tab[i])
            return true;
        if(!Miller_Rabbin(n,tab[i]))
            return false;    
    }
    return true;
}

int main()
{
    int i,N;
    long tmp, count;
    while(scanf("%d",&N)!=EOF)
    {
        count = 0;
        for(i=0;i<N;i++)
        {
            scanf("%ld",&tmp);
            if(IsPrime(tmp))
                count++;
        }
        printf("%d\n",count);
    }
}

7.筛选法

1999 1286 2098

 

8.素数的筛选法,穷举,因数,判定等

#include<iostream>

using namespace std;

bool prime[10000+5];

void Init()
{
    for(int i = 2; i <= 10000; ++i)
    {
        prime[i] = true;
    }
    for(int i =2;i <= 10000; ++i)
    {
        if(prime[i] == true)
        {
            for(int j = 2; i*j <= 10000; ++j)
                prime[i*j] = false;
        }
    }
}
//保存素数
#include<iostream>
#include<string.h>
using namespace std;

#define N 100001
bool IsPrime[N];
int Prime[N],cnt;

void Init_Prime_Table()
{
    long long int i,j;//注意,i比较大时会容易超int的范围。
     
    cnt = 0;
    memset(IsPrime,true,sizeof(IsPrime));
    IsPrime[1] = false;
    for(i=2;i<=N;i++)
    {
        if(IsPrime[i])
        {
            Prime[cnt++] = i;
            for(j=i*i;j<=N;j+=i)
                IsPrime[j] = false;
        }
    }
}


int main()
{
    Init_Prime_Table();
    for(int i=0;i<1000;i++)
    {
        printf("%5d",Prime[i]);
    } 
    
    return 0;
}

2098 2161

 

9.普通素数判定

bool IsPrime(int n)
{
    int i = 0;
    if(n<=2) return false;
    for(i=2;i*i<=n;i++)
    {
        if(n%i==0)
            return false;
    }
    return true;
}

 

 

几何\ 多边形 多边形切割 浮点函数 几何公式 面积 球面 三角形 三维几何 凸包(graham) 网格(pick) 圆 整数函数 注意 结构\ 并查集 并查集扩展(friend_enemy)(binary)(mapped) 矩形切割 线段树 线段树扩展 线段树应用 子段和 子阵和 其他\ 大数(整数类封装) 分数 矩阵 线性方程组(gauss) 日期 线性相关 数论\ 阶乘最后非零位 线性方程() 质数表 质数随机判定(miller_rabin) 质因数分解 最大公约数欧拉函数 数计算\ 定积分计算(Romberg) 多项式求根(牛顿法) 周期性方程(追赶法) 图论_NP搜索\ 最大团(n小于64) 最大团 图论_连通性\ 无向图关键边(dfs邻接阵形式) 无向图关键点(dfs邻接阵形式) 无向图块(bfs邻接阵形式) 无向图连通分支(bfs邻接阵形式) 无向图连通分支(dfs邻接阵形式) 有向图强连通分支(bfs邻接阵形式) 有向图强连通分支(dfs邻接阵形式) 有向图最小点基(邻接阵形式) 图论_匹配\ 二分图最大匹配(hungary邻接表形式) 二分图最大匹配(hungary邻接阵形式) 二分图最大匹配(hungary邻接表形式,邻接阵接口) 二分图最大匹配(hungary正向表形式) 二分图最佳匹配(kuhn_munkras邻接阵形式) 一般图最大匹配(邻接表形式) 一般图最大匹配(邻接阵形式) 一般图最大匹配(正向表形式) 一般图匹配(邻接表形式,邻接阵接口) 图论_网络流\ 上下界最大流(邻接阵形式) 上下界最小流(邻接阵形式) 上下界最大流(邻接表形式) 上下界最小流(邻接表形式) 最大流(邻接阵形式) 最大流(邻接表形式) 最大流(邻接表形式,邻接阵接口) 最大流无流量(邻接阵形式) 最小费用最大流(邻接阵形式) 图论_应用\ 欧拉回路(邻接阵形式) 前序表化 树的优化算法 拓扑排序(邻接阵形式) 最佳边割集 最佳顶点割集 最小边割集 最小顶点割集 最小路径覆盖 图论_最短路径\ 最短路径(单源bellman_ford邻接阵形式) 最短路径(单源dijkstra邻接阵形式) 最短路径(单源dijkstra_bfs邻接表形式) 最短路径(单源dijkstra_bfs正向表形式) 最短路径(单源dijkstra+binary_heap邻接表形式) 最短路径(单源dijkstra+binary_heap正向表形式) 最短路径(单源dijkstra+mapped_heap邻接表形式) 最短路径(单源dijkstra+mapped_heap正向表形式) 最短路径(多源floyd_warshall邻接阵形式) 图论_支撑树\ 最小生成树(kruskal邻接表形式) 最小生成树(kruskal正向表形式) 最小生成树(prim邻接阵形式) 最小生成树(prim+binary_heap邻接表形式) 最小生成树(prim+binary_heap正向表形式) 最小生成树(prim+mapped_heap邻接表形式) 最小生成树(prim+mapped_heap正向表形式) 最小树形图(邻接阵形式) 应用\ joseph拟 N皇后构造解 布尔母函数 第k元素 幻方构造 式匹配(kmp) 逆序对数 字符串最小表示 最长公共单调子序列 最长子序列 最大子串匹配 最大子段和 最大子阵和 组合\ 排列组合生成 生成gray码 置换(polya) 字典序全排列 字典序组合 组合公式
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值