您的位置:首页 > 其它

数论模板,待更新。。。

2016-05-12 17:38 337 查看
整数快速幂

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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: