整数快速幂
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; }
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; }
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; } } }
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; }
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); }