高精单精
1 void multi(Bign& a,int x) 2 3 { 4 5 for(int j=0;j<a.len;j++) a.N[j] *= x; 6 7 int i=0; 8 9 while(i<a.len || a.N[i]>10) { 10 11 a.N[i+1] += a.N[i]/10; 12 13 a.N[i] %= 10; 14 15 i++; //i++ 16 17 } 18 19 if(a.N[i]) a.len=i+1; //判断 20 21 else a.len=i; 22 23 } 24 25 26 27 void div(Bign& a,int x) { 28 29 for(int i=a.len-1;i>0;i--) { //由高位到低位 30 31 a.N[i-1] += a.N[i]%x*10; 32 33 a.N[i] /= x; 34 35 } 36 37 a.N[0]/=x; //最后一位 38 39 while(a.N[a.len-1]==0) a.len--; //删除前导0 40 41 }
高精高精乘
1 const int maxn = 3001; 2 3 const int BASE=10; 4 5 struct Bign{ 6 7 int len,N[maxn]; 8 9 void init(int n) { 10 11 memset(N,0,sizeof(N)); 12 13 len=1; N[0]=n; 14 15 int i=0; 16 17 while(N[i]>=BASE) { 18 19 N[i+1] += N[i]/BASE; 20 21 N[i] %= BASE; 22 23 i++; 24 25 } 26 27 if(N[i]) len=i+1; 28 29 else len=i; 30 31 } 32 33 }; 34 35 36 37 Bign a,b; 38 39 40 41 Bign multi_B(Bign a,Bign b) { 42 43 Bign c; c.init(0); c.len=a.len+b.len; 44 45 for(int i=0;i<a.len;i++) 46 47 for(int j=0;j<b.len;j++) { 48 49 c.N[i+j] += a.N[i]*b.N[j]; 50 51 c.N[i+j+1] += c.N[i+j]/BASE; 52 53 c.N[i+j] %= BASE; 54 55 } 56 57 while(c.len>0 && c.N[c.len-1]==0) c.len--; 58 59 return c; 60 61 }
快速幂:
1 LL pow(int p , int x,) { //p^x 2 3 LL tmp=p,ans=1; 4 5 while(x) { 6 7 if(x&1) ans=(ans*tmp)%1000; 8 9 tmp=(tmp*tmp)%1000; 10 11 x>>=1; 12 13 } 14 15 return ans; 16 17 } 18 19
求素数:
1 void get_primes(int n) { 2 3 bool su[maxn]; memset(su,true,sizeof(su)); 4 5 for(int i=2;i<=n;i++) if(su[i]) { 6 7 primes.push_back(i); 8 9 if(i<=sqrt(n)) for(int j=i*i;j<=n;j+=i) su[j]=false; 10 11 //i<=sqrt(n) 否则RE 12 13 } 14 15 } 16 17
唯一分解:
1 void calc(int x,int d) { 2 3 for(int i=0;i<primes.size();i++) { 4 5 while(x%primes[i]==0) { 6 7 e[i] += d; 8 9 x /= primes[i]; 10 11 } 12 13 if(x==1) break; 14 15 } 16 17 }
公式:
Stirling 数:
1 int Sx[100][100]; 2 3 4 5 inline int S(int n,int k) { 6 7 if(Sx[n][k]) return Sx[n][k]; 8 9 10 11 if(k==0 || k>n) return 0; 12 13 if(k==n) return 1; 14 15 16 17 return Sx[n][k]=S(n-1,k-1)+k*S(n-1,k); 18 19 } 20 21
组合公式:
1 for(int i=1;i<=n;i++) 2 3 { 4 5 C[i][0]=0; C[i][i]=1; 6 7 for(int j=1;j<i;j++) 8 9 C[i][j]=C[i-1][j-1]+C[i-1][j]; 10 11 } 12 13
Catalan数://C(2n,n)/(n+1)
1 h[1]=1; 2 3 for(int i=2;i<=n;i++) h[i]=h[i-1]*(4*i-2)/(i+1); 4 5
错排公式(高精): //Dn=(n+1)(Dn-2+Dn-1) //D1=0,D2=1;
1 Bign D[3]; 2 3 D[0].len=D[1].len=D[2].len=1; D[0].N[0]=1; D[1].N[0]=0; 4 5 for(int i=2;i<=n;i++) 6 7 { 8 9 memset(D[2].N,0,sizeof(D[2].N)); 10 11 Add(D[2],D[0]); Add(D[2],D[1]); 12 13 multi(D[2],i-1); 14 15 D[0]=D[1]; D[1]=D[2]; 16 17 } 18 19 for(int i=D[2].len-1;i>=0;i--) cout<<D[2].N[i]; 20 21
矩阵相乘:
1 LL multi(int y,int cnt) { 2 if(!cnt) return 0; 3 if(cnt==1) return y%m; 4 LL res=multi(y,cnt/2); 5 res=(res+res)%m; 6 if(cnt&1) res=(res+y)%m; 7 return res; 8 } 9 10 struct Matrix{ 11 int r,c; 12 LL N[maxn][maxn]; 13 void init(int r,int c) { 14 this->r=r, this->c=c; 15 memset(N,0,sizeof(N)); 16 } 17 Matrix operator*(Matrix& B)const{ 18 Matrix C; 19 C.init(r,B.c); 20 for(int i=0;i<C.r;i++) 21 for(int j=0;j<C.c;j++) 22 { 23 for(int k=0;k<c;k++) C.N[i][j] += multi(N[i][k],B.N[k][j]); 24 C.N[i][j]%=m; 25 } 26 return C; 27 } 28 Matrix pow(LL p) { 29 Matrix tmp=*this; 30 Matrix ans; 31 ans.init(r,r); 32 for(int i=0;i<r;i++) ans.N[i][i]=1; 33 while(p) { 34 if(p&1) ans=ans*tmp; 35 tmp=tmp*tmp; 36 p>>=1; 37 } 38 return ans; 39 } 40 };
大整数开方: