(1)素数判定
bool prime(int x)
{
for(int i=2;i*i<=maxn;i++) //降低时间复杂度
if(x%i==0)
return false;
return true;
}
(2)筛法素数打表
void getprime(int n)
{
int k=0,ans[maxn];
memset(ans,0,sizeof(ans));
ans[0]=ans[1]=1;
for(int i=2;i<=n;i++)
{
if(!ans[i])
for(int j=i*i;j<=n;j+=i)
ans[j]=1; //标记变量
}
for(int i=2;i<=n;i++)
if(!ans[i]) //值为0的都是素数
ans[k++]=i;
ans[k]='\0';
for(int i=0;ans[i]!='\0';i++)
cout<<ans[i]<<" ";
cout<<endl;
}
(3)唯一分解定理
即:每个大于1的自然数均可写为质数的积,而且这些素因子按大小排列之后,写法仅有一种方式。
void W(int n)
{
int k=0,s[maxn];
for(int i=2;i<=n;i++)
{
if(n%i==0)
{
while(n%i==0) //一定能保证i为素数
n/=i;
s[k++]=i;
}
}
for(int i=0;i<k;i++)
cout<<s[k]<<" ";
cout<<endl;
}
(4)欧拉公式
N(n)=n*(1-1/p1)*(1-1/p2)···(其中p1、p2为能被n整除的素因子)
void euler_phi(int n)
{
int sum=n;
for(int i=2;i<=n;i++)
{
if(n%i==0)
{
sum=sum/i*(i-1);
while(n%i==0)
n/=i;
}
}
if(n>1)
sum=sum/n*(n-1);
cout<<sum<<endl;
}
(5)GCD
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);//不断递归
}
(6)扩展GCD(求出x,y,满足Ax+By=gcd(A,B))
int extend_gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int r=extend_gcd(b,a%b,y,x);
y-=x*(a/b);
return r;
}
(7)中国剩余定理(中国剩余定理 求出方程组x=a(i)(mod m(i))(0<=i)
int CRT(int a[],int m[],int n)
{
int M=1;
for(int i=0;i<n;i++)
M*=m[i];
int ret=0;
for(int i=0;i<n;i++)
{
int x,y;
int tm=M/m[i];
extend_gcd(tm,m[i],x,y);
ret=(ret+tm*x*a[i])%M;
}
return (ret+M)%M;
}
(8)进制转换(x进制的数转换成y进制)
string transform(int x,int y,string s)
{
string res="";
int sum=0;
for(int i=0;i<s.length();i++)
{
if(s[i]=='-')
continue;
if(s[i]>='0'&&s[i]<='9') //十进制以内
sum=sum*x+s[i]-'0';
else
sum=sum*x+s[i]-'A'+10; //十进制之外
}
while(sum)
{
char tmp=sum%y;
sum/=y;
if(tmp<=9)
tmp+='0';
else
tmp=tmp-10+'A';
res=tmp+res;
}
if(res.length()==0)
res="0";
if(s[0]=='-')
res='-'+res;
return res;
}
(9)快速幂取模(求a的i次幂对n的模)
void quickpow_mod(int a,int i,int n)
{
int k=a%n,sum=1;
while(i)
{
if(i&1)
sum=sum*k%i;
k=k*k%a;
n>>=1;
}
cout<<sum<<endl;
}
(10)星期计算(蔡勒公式 给定一个日期,求出这一天是星期几,返回ans,表示是星期(ans+1) )
int whatday(int day,int mon,int year)
{
int ans;
if(mon==1||mon==2)
{
mon+=12;
year--;
}
if((year<1752)||(year==1752&&mon<9)||(year==1752&&mon==9&&day<3))
{//当日期在1752年9月3日之前
ans=(day+2*mon+3*(mon+1)/5+year+year/4+5)%7;
}
else
ans=(day+2*mon+3*(mon+1)/5+year+year/4-year/100+year/400)%7;
return ans;
}
(11)闰年判断
bool Isleap(int year)
{
if(year%400==0||year%100&&year%4==0)
return true;
return false;
}
(12)日期计算
int leap(int y)
{
if(!y)
return 0;
return y/4-y/100+y/400;
}
int calc(int day,int mon,int year)
{
int res=(year-1)*day+leap(year-1);
int s[12]={31,28,31,30,31,30,31,31,30,31,30,31};
for(int i=1;i<mon;i++)
res+=s[i];
if(Isleap(year)&&mon>2)
res++;
res+=day;
return res;
}
void count_day(int da,int ma,int ya,int db,int mb,int yb)
{
int resa=calc(da,ma,ya);
int resb=calc(db,mb,yb);
cout<<abs(resa-resb)<<endl;
}