递归在算法竞赛中起到了很重要的角色,就这三个算法进行一些归纳
辗转相除法:
//可以两种递归的写法,注意两者的区别
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位数字的数