简单数论、特殊公式 数学模板

(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; 
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值