数论模板,待更新。。。

整数快速幂

LL My_Pow(LL x,LL n){//返回x^n
    LL ret=1;
    while(n>0){
        if(n&1){
            ret*=x;
        }
        x*=x;
        n>>=1;
    }
    return ret;
}

a*b%c

LL Mult_Mod(LL  a,LL b,LL c){//返回a*b%c
    a%=c;
    b%=c;
    LL ret=0;
    LL tmp=a;
    while(b){
        if(b&1){
            ret+=tmp;
            if(ret>c)ret-=c;//%c
        }
        tmp<<=1;
        if(tmp>c)tmp-=c;
        b>>=1;
    }
    return ret;
}

a^b%c

LL Pow_Mod(LL a,LL b,LL c){//返回a^b%c
    LL ret=1;
    LL temp=a%c;
    while(b){
        if(b&1)ret=Mult_Mod(ret,temp,c);
        temp=Mult_Mod(temp,temp,c);
        b>>=1;
    }
    return ret;
}

一元线性同余方程;

ax+ny=b;
令d=gcd(a,n);
当d|b时,方程有d个解(有d个不同的x),否则无解;ax0+ny0=d;
可得ax+by=c的一个解x=x0*c/d;
那么通解xi=x0+i(n/d);0<=i<=d-1
最小正解x=(x0%(n/d)+n/d)%(n/d);
x0%(n/d)  把x0调到了(-(n/d-1),n/d-1)的位置
+n/d把它变成正数,取模变成最小的正解
每一步计算得到的ans都是通解的一部分;



素数打表:线性筛

void getprim(){
    memset(prim,0,sizeof(prim));
    for(int i=2;i<=SIZE;i++){
        if(!prim[i])prim[++prim[0]]=i;
        for(int j=1;j<=prim[0]&&prim[j]<=SIZE/i;j++){
            prim[prim[j]*i]=1;
            if(i%prim[j]==0)break;
        }
    }
    printf("%d\n",prim[0]);//prim[0]表示2-size内的素数的个数
}

普通筛

int prim[SIZE];
void get_prim(){
    memset(prim,0,sizeof(prim));
    for(LL i=2;i<SIZE;i++){
        if(!prim[i]){
            prim[++prim[0]]=i;
            for(LL j=i*i;j<SIZE;j+=i)
                prim[j]=1;
        }
    }
}

判断一个数是否是素数,prim为sqrt(n)内的素数

bool is_prim(int n){
    if(n==1)return false;
    for(int i=1,k=(int)sqrt((double)n);prim[i]<=k;i++)
        if(n%prim[i]==0)return false;
    return true;
}

ex_gcd

long long extend_gcd(long long a,long long b,long long &x,long long &y){
    if(a==0&&b==0)return -1;//无gcd
    if(b==0){x=1;y=0;return a;}
    long long d=extend_gcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
long long gcd(long long a,long long b){
    if(b==0)return a;
    return gcd(b,a%b);
}


你可能感兴趣的:(数论模板,待更新。。。)