辗转相除,二进制一的个数,快速幂算法使用递归的相同处

递归在算法竞赛中起到了很重要的角色,就这三个算法进行一些归纳

辗转相除法:

//可以两种递归的写法,注意两者的区别

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


int gcd(int a,int b)
{
    if(b==0) return a;
    return gcd(b,a%b);//注意:在这里一定要return,上面的return只能用一次,通过这个
                      //return我们可以实现一个延续,当然既然可以延续就可以在返回的
                      //过程中进行修改,在下面的快速幂算法中会有提及
}

二进制一的个数:



int bitcount(int x){
	return x==0?0:bitcount(x/2)+(x&1);//x&1加括号 
}

//想装大佬就写上面代码,很精简
int bitcount(int x){
	if(x==0)
         return 0;
        return bitcount(x/2)+(x&1);//x为奇数时加一
}

int bitcount(int x)
{
    int res=0;
    while(x>0)
    {
        if(x&1) res++;
        x>>=1;
    }
    return 0;
}

快速幂算法:

LL mod_pow(LL a,LL b,LL mod)
{
	int res=1;
	while(b>0)
	{
		if(b&1) res=res*a%mod;//如果是奇数,则运行 
		a=a*a%mod;
		b>>=1; 
	}
	return res;
}
//上下两个算法实现一样功能,算法复杂度均为log(n)
LL mod_pow(LL a,LL b,LL mod)
{
	if(b==0) return 1;
	LL res=mod_pow(a*a%mod,b/2,mod);
	if(b&1) res=res*a%mod;
	return res;//这里是不是和上面算法的代码很像呢
           //他们都是先递归到最深处,然后返回的时候可以进行相应返回值的修改想要实
           //现这个效果,刚开始一定得if(b==0)这样的判断条件,其实这三个算法特别像!!!
}

 再插入点当自己的笔记(可以忽略):

素数常用代码:


LL ol(LL x)//欧拉定理:降幂定理, 
{//该函数用来返回与x在(1,x-1)中互质的个数 
	int res=x;
	for(int i=2;i*i<=x;i++)
	{
		if(x%i==0)
		{
			res=res-res/i;
			while(x%i==0)
			{
				x/=i;
			}
		}
		if(x>1)
		res=res-res/x;
	}
	return res;
}


//
void prime(int k)
{
    for(int i=2;i*i<=k;i++)
    {
        while(k%i==0)
        {
            vec.push_back(i);
            k/=i;
        }
    }
    if(k>1)
    vec.push_back(k);
}

 树状数组:

//树状数组输入的一组数据可以不存

#include "bits/stdc++.h"
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
const int maxn = 1e5+7;
int a[maxn],b[maxn];
void build(int i,int n)
{
	int k=i;
		while(k<=n)
		{
			b[k]+=a[i];
			k+=k&-k;
		}
}
int search(int a)
{
	int sum=0;
	while(a!=0)
	{
		sum+=b[a];
		a-=a&-a;
	}
	return sum;
}
void change(int num,int c)
{
	int cut=num-a[num];
		int k=num;
		while(k<=n)
		{
			b[k]+=cut;
			k+=k&-k;
		}
}
int main()
{
	int n;
	cin>>n;
	rep(i,1,n)
	cin>>a[i],build(i,n);
	rep(i,1,n)
	cout<<b[i]<<endl;
	int a1,b1;
	rep(i,1,5)
	cout<<search(i)<<endl;
	int ans=b[b1]-b[a1];
	cout<<ans<<endl;
	return 0;
}
//心血来潮在插点
//判断long long最大储存数据,2的62次方是可以的,63就不行了
#include "bits/stdc++.h"


using namespace std;


int main()
{
	long long a;
	a=pow(2,62);
	cout<<a<<endl;
	return 0;
}//运行结果如下,是一个19位数字的数

 零点半南昌航空大学405宿舍完成!!!

猜你喜欢

转载自blog.csdn.net/weixin_41466575/article/details/82731469