数论模板

1. 辗转相除法(欧几里得除法)

int gcd(int a,int b)
{
	return b==0?a:gcd(b,a%b);
}

或者c++直接用函数__gcd()

2.扩展欧几里得

int exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1;
		y=0;
		return a;
	}
	int k=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return k;
}

3.素数筛 —— NlogN

void getprime()
{
	int n=sqrt(m+0.5);
	memset(vis,false,sizeof vis);
	for(int i=2;i<=n;i++)
	{
		if(vis[i]==false)
		{
			for(int j=i*i;j<=n;j+=i)
			vis[j]=true;
		}
	}
}

vis数组中false为素数,可以1e7的数据量

欧拉筛(线性筛) —— N

void getprime()
{
	bool vis[100001000];
	int prime[1000100];//存所有的素数
	int pl=0;//prime数组的长度
	for(int i=2;i<=10000000;i++)
	{
		if(vis[i]==false)
		prime[++pl]=i;
		for(int j=1;j<pl&&i*prime[j]<max_;j++)
		{
			vis[i*prime[j]]=true;
			if(i%prime[j]==0)
			break;
		}
	}
}

筛出后放到了prime数组中,最多可解1e8

4.二分递归求等比数列前n项和

a+a^2+a^3+...+a^n

①n为偶数

原式=(a+a^2+...+a^n/2)(1+a^n/2)

②n为奇数

原式=(a+a^2+...+a^n/2)(1+a^n/2+1)+a^n/2+1

ll f(ll p,ll n)
{
	if(n==0)
	return 1;
	if(n&1)
	return (f(p,n/2)*(1+fpow(p,n/2+1)))%mod+fpow(p,n/2+1)%mod;
	else
	return (f(p,n/2)*(1+fpow(p,n/2))%mod;
}

5.算数基本定理(唯一分解定理)

可以证明,数x分解后的最大素数要么小于 x,要么幂为1,所以只要判到下即可,最后再特判结果是否为1,可大大减小时间复杂度

for(int i=2;i*i<=a;)
{
	if(tmp%i==0)
	{
		num[++pl]=i;
		flag=1;
	}
	while(tmp%i==0)
	{
		tmp/=i;
		cnt[pl]++;
	}
	if(tmp==1)
	break;
	if(i==2)
	i++;
	else
	i+=2;
}
if(tmp!=1)
{
	num[++pl]=tmp;
	cnt[pl]=1;
}

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Lngxling/article/details/79953573
个人分类: 板子
想对作者说点什么? 我来说一句

ACM数论模板~。。。

2010年07月20日 145KB 下载

ACM模板 数论

ACM模板 数论

gdymind gdymind

2017-01-05 20:50:03

阅读数:317

没有更多推荐了,返回首页

不良信息举报

数论模板

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭