数学模板
/*最大公约数性质 gcd(a,b)=gcd(b,a) (交换律) gcd(-a,b)=gcd(a,b) gcd(a,a)=|a| gcd(a,0)=|a| gcd(a,1)=1 gcd(a,b)=gcd(b, a mod b) gcd(a,b)=gcd(b, a-b) 如果有附加的一个自然数m, 则: gcd(ma,mb)=m * gcd(a,b) (分配律) gcd(a+mb ,b)=gcd(a,b) 如果m是a和b的最大公约数, 则: gcd(a/m ,b/m)=gcd(a,b)/m 在乘法函数中有: gcd(ab,m)=gcd(a,m) * gcd(b,m) 两个整数的最大公约数主要有两种寻找方法: * 两数各分解质因数,然后取出同样有的质因数乘起来 *辗转相除法(扩展版) 和最小公倍数(lcm)的关系: gcd(a, b) * lcm(a, b) = ab a与b有最大公约数, 两个整数的最大公因子可用于计算两数的最小公倍数,或分数化简成最简分数。 两个整数的最大公因子和最小公倍数中存在分配律: * gcd(a, lcm(b, c)) = lcm(gcd(a, b), gcd(a, c)) * lcm(a, gcd(b, c)) = gcd(lcm(a, b), lcm(a, c)) 在坐标里,将点(0, 0)和(a, b)连起来,通过整数坐标的点的数目(除了(0, 0)一点之外)就是gcd(a, b)。 */ const int maxn = 10000000 + 10; const int maxp = 700000; int vis[maxn]//vis[i] = 1,则i是合数,vis[i] = 0,则i是1或者素数 int prime[maxp]; //筛素数 void sieve(int n){ int m = (int)sqrt(n+0.5);//避免浮点误差 memset(vis,0,sizeof(vis)); for(int i = 2;i <= m;i++) if(!vis[i]) for(int j = i*i;j <= n;j+=i)vis[j]=1; } //生成素数表,放在prime数组中,返回素数个数 int gen_primes(int n){ sieve(n); int c = 0; for(int i = 2;i <= 2;i++) if(!vis[i]) prime[c++] = i; return c; } //扩展欧几里得,注意求得的x,y对应|x| + |y| 的最小值 typedef long long ll; ll gcd(ll a,ll b){ return b == 0 ? a : gcd(b,a%b); } void exgcd(ll a,ll b,ll& d,ll& x,ll& y){ if(!b){ d = a; x = 1; y = 0; } else{ exgcd(b,a%b,d,y,x); y -= x*(a/b); } } /*模运算法则 模数不能是0 (a+b)%n = ((a%n) + (b%n))%n (a-b)%n = ((a%n) - (b%n) + n)%n ab % n = (a % n)(b % n)%n 同余关系的自反、对称、传递。 若a≡c(mod p),b≡d(mod p), 则a+b≡c+d,a-b≡c-d,ab≡cd(mod p) 若ac≡bd,c≡d(mod p),且gcd(c,m)=1 则a≡b(mod p)*/ //快速乘快速幂 ll q_mul(ll a,ll b,ll mod){ ll ans = 0; while(b){ if(b&1){ b--; ans = (ans + a) % mod; } b/=2; a = (a + a) % mod; } return ans; } ll q_pow(ll a,ll b,ll mod){ ll ans = 1; while(b){ if(b&1){ ans = q_mul(ans,a,mod); } b/=2; a = q_mul(a,a,mod); } return ans; } //欧拉phi函数 int phi[maxn]; void phi_table(int n){ for(int i = 2;i <= n;i++) phi[i] = 0; phi[1] = 1; for(int i = 2;i <= n;i++) if(!phi[i]) for(int j = i;j <= n;j+=i){ if(!phi[j]) phi[j] = j; phi[j] = phi[j] / i * (i-1); } } ll euler_phi(ll x){ ll m = (ll)sqrt(x+0.5); ll ans = x; for(int i = 2;i <= m;i++){ if(x % i == 0){ ans = ans / i * (i-1); while(x % i == 0) x /= i; } } if(x > 1) ans = ans / x * (x-1); return ans; } //逆元 ll inv(ll a,ll n){ ll d,x,y; gcd(a,n,d,x,y); return d == 1 ? (x+n)%n : -1; } ll inv2(ll a,ll n){ return q_pow(a,n-2,n); } //中国剩余定理 //n个方程: x= a[i](mod m[i]) (0<=i<n) ll china(int n,int* a,int* m){ ll M = 1,d,y,x = 0; for(int i = 0;i < n;i++) M *= m[i]; for(int i = 0;i < n;i++){ ll w = M / m[i]; gcd(m[i],w,d,d,y); x = (x + y*w*a[i]) % M; } return (x+M) % M; } //求解模方程a^x=b(mod n)。n为素数,无解时返回-1 int log_mod(int a,int b,int n){ int m,v,e=1,i; m = (int)sqrt(n+0.5); v = inv(q_pow(a,m,n),n); map<int,int> x; x[1] = 0; for(int i = 1;i < m;i++){ e = q_mul(e,a,n); if(!x.count(e)) x[e] = i; } for(i = 0;i < m;i++){ if(x.count(b)) return i*m + x[b]; b = q_mul(b,v,n); } return -1; } //高斯消元 typedef double Matrix[maxn][maxn]; void gauss_elimination(Matrix A,int n){ int i,j,k,r; //消元过程 for(int i = 0;i < n;i++){ //选一行r并与第i行交换 r = i; for(j = i+1;j < n;j++) if(fabs(A[j][i]) > fabs(A[r][i])) r = j; if(r != i) for(j = 0;j <= n;j++) swap(A[r][j],A[i][j]); //与第i+!~n行进行消元 for(k = i+1,k < n;k++){ double f = A[k][i] / A[i][i]; for(j = i;j <= n;j++) A[k][j] -= f * A[i][j]; } } for(int i = n-1;i >= 0;i--){ for(j = i+1;j < n;j++) A[i][n] -= A[j][n] * A[i][j]; A[i][n] /= A[i][i]; } } //秦九韶算法 int i = 1,v = a[n]; while(i <= n){ v = v*x + a[n-i]; i++; } ans = v; //进制转换 //m转10 #include <iostream> #include <cstring> #include <cmath> using namespace std; int main(){ int a[100]; int m,sum=0; string n; cin>>n>>m; a[0]=n.size(); for(int i=1;i<=a[0];i++){ if(n[a[0]-i]>='0'&&n[a[0]-i]<='9') sum=sum+pow(m,i-1)*(n[a[0]-i]-'0'); else sum=sum+pow(m,i-1)*(n[a[0]-i]-'A'+10); } cout<<sum; } //10转m int m,b; char str[1000000]; void change_base(int n,int base,char *s){ if(n){ change_base(n/base,base,s); s[strlen(s)]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[n%base]; }else return; } int main(){ cin >> m >> b; change_base(m,b,str); cout << str << endl; return 0; } //高精度 #include <cstdio> #include <cmath> #include <iostream> #include <cstring> using namespace std; const int P=10000,L=5000,W=4; char s[L*W]; struct Big { int len;int data[L];bool fu; void clear() { memset(data,0,sizeof(data)); len=0;fu=false; } int& operator [] (int k) { return data[k]; } void operator = (int k) { clear(); if (k<0) fu=true,k=-k;else fu=false; len=0; while (k) data[++len]=k%P,k/=P; if (len==0) len=1; } bool operator < (Big b) { bool t=false; if (fu && !b.fu) return true; if (!fu && b.fu) return false; if (fu && b.fu) t=true; if (len<b.len) return true^t; if (len>b.len) return false^t; for (int i=len;i;--i) { if (data[i]<b[i]) return true^t; if (data[i]>b[i]) return false^t; } return false; } bool operator <= (Big b) { bool t=false; if (fu && !b.fu) return true; if (!fu && b.fu) return false; if (fu && b.fu) t=true; if (len<b.len) return true^t; if (len>b.len) return false^t; for (int i=len;i;--i) { if (data[i]<b[i]) return true^t; if (data[i]>b[i]) return false^t; } return true; } bool operator > (Big b) { bool t=false; if (fu && !b.fu) return false; if (!fu && b.fu) return true; if (fu && b.fu) t=true; if (len<b.len) return false^t; if (len>b.len) return true^t; for (int i=len;i;--i) { if (data[i]<b[i]) return false^t; if (data[i]>b[i]) return true^t; } return false; } bool operator >= (Big b) { bool t=false; if (fu && !b.fu) return false; if (!fu && b.fu) return true; if (fu && b.fu) t=true; if (len<b.len) return false^t; if (len>b.len) return true^t; for (int i=len;i;--i) { if (data[i]<b[i]) return false^t; if (data[i]>b[i]) return true^t; } return true; } bool operator == (Big b) { if (fu!=b.fu) return false; if (len<b.len) return false; if (len>b.len) return false; for (int i=len;i;--i) if (data[i]!=b[i]) return false; return true; } bool operator == (int k) { if (k<0) { if (!fu) return false; k=-k; } else if (fu) return false; if (k>=P) { Big b;b=k; return *this==b; } else return len==1 && data[1]==k; } bool operator != (Big b) { if (fu!=b.fu) return true; if (len<b.len) return true; if (len>b.len) return true; for (int i=len;i;--i) if (data[i]!=b[i]) return true; return false; } bool operator != (int k) { if (k<0) { if (!fu) return true; k=-k; } else if (fu) return true; if (k>=P) { Big b;b=k; return *this!=b; } else return !(len==1 && data[1]==k); } Big operator + (Big b) { Big a=*this,c;c.clear(); if (a.fu && b.fu) { a.fu=false;b.fu=false;c=a+b; if (c.len!=1 || c[1]!=0) c.fu=true; return c; } if (a.fu && !b.fu) {a.fu=false;return b-a;} if (!a.fu && b.fu) {b.fu=false;return a-b;} a.len=max(a.len,b.len); for (int i=1;i<=a.len;++i) { a[i+1]+=(a[i]+b[i])/P; a[i]=(a[i]+b[i])%P; } if (a[a.len+1]) ++a.len; while (a[a.len]==0 && a.len>1) --a.len; return a; } Big operator + (int k) { Big a=*this,b;b=k; return a+b; } Big operator - (Big b) { Big a=*this,c;c.clear(); if (a.fu && !b.fu) { a.fu=false;b.fu=false;c=a+b; if (c.len!=1 || c[1]!=0) c.fu=true; return c; } if (a.fu && b.fu) { a.fu=false;b.fu=false;return b-a; } if (!a.fu && b.fu) { b.fu=false; return a+b; } if (a<b) swap(a,b),a.fu=true;else a.fu=false; for (int i=1;i<=a.len;++i) { if (a[i]<b[i]) a[i]+=P,--a[i+1]; a[i]-=b[i]; } while (a[a.len]==0 && a.len>1) --a.len; if (a.len==1 && a[1]==0) a.fu=false; return a; } Big operator - (int k) { Big a=*this,b;b=k; return a-b; } Big operator * (Big b) { Big c;c.clear(); c.len=len+b.len-1; for (int i=1;i<=len;++i) for (int j=1;j<=b.len;++j) { c[i+j-1]+=data[i]*b[j]; c[i+j]+=c[i+j-1]/P; c[i+j-1]%=P; } if (c[c.len+1]) ++c.len; while (c[c.len]==0 && c.len>1) --c.len; c.fu=fu^b.fu; if (c.len==1 && c[1]==0) c.fu=false; return c; } Big operator * (int k) { Big a=*this; if (k<0) a.fu=!a.fu,k=-k; if (k>=P) { Big b;b=k; return a*b; } for (int i=1;i<=a.len;++i) a[i]*=k; for (int i=1;i<=a.len;++i) a[i+1]+=a[i]/P,a[i]%=P; while (a[a.len+1]) { ++a.len; a[a.len+1]=a[a.len]/P; a[a.len]%=P; } while (a[a.len]==0 && a.len>1) --a.len; if (a.len==1 && a[1]==0) a.fu=false; return a; } Big operator / (int k) { Big a=*this;int g=0; if (k<0) a.fu=!a.fu,k=-k; for (int i=a.len;i;--i) { a[i]+=g*P; g=a[i]%k; a[i]/=k; } while (a[a.len]==0 && a.len>1) --a.len; if (a.len==1 && a[1]==0) a.fu=false; return a; } Big operator % (int k) { Big b;b=k; return *this%b; } Big operator / (Big b) { Big c,d;c=0;d=0;c.fu=fu^b.fu;b.fu=false; for (int i=len;i;--i) { d=d*P+data[i]; int ans=0,l=0,r=P-1; while (l<=r) { int mid=(l+r)>>1; if (b*mid<=d) ans=mid,l=mid+1; else r=mid-1; } c[i]=ans; d=d-b*c[i]; } c.len=len; while (c[c.len]==0 && c.len>1) --c.len; return c; } Big operator % (Big b) { Big c,d;c=0;d=0;c.fu=fu^b.fu;b.fu=false; for (int i=len;i;--i) { d=d*P+data[i]; int ans=0,l=0,r=P-1; while (l<=r) { int mid=(l+r)>>1; if (b*mid<=d) ans=mid,l=mid+1; else r=mid-1; } c[i]=ans; d=d-b*c[i]; } c.len=len; while (c[c.len]==0 && c.len>1) --c.len; d=*this-b*c; return d; } Big operator ^ (int t) { Big a=*this,ans;ans=1; while (t) { if (t&1) ans=ans*a;t>>=1;a=a*a; } return ans; } void read() { scanf("%s",s); clear(); len=1; int pow=1,t=1,l=strlen(s),stop=0; if (s[0]=='-') fu=true,stop=1; for (int i=l-1;i>=stop;--i) { if (t>W) t=pow=1,++len; data[len]+=pow*(s[i]-'0'); ++t,pow*=10; } } void write() { if (fu) printf("%c",'-'); printf("%d",data[len]); for (int i=len-1;i;--i) { if (data[i]<10) putchar('0'); if (data[i]<100) putchar('0'); if (data[i]<1000) putchar('0'); printf("%d",data[i]); } } void writeln() { write();printf("\n"); } } ; Big ans,tmp; int main(){ ans.read(); tmp = ans; ans = ans * 333; tmp.writeln(); return 0; } //miller rabin判素 typedef unsigned long long LL; LL modular_multi(LL x,LL y,LL mo) { LL t; x%=mo; for(t=0;y;x=(x<<1)%mo,y>>=1) if (y&1) t=(t+x)%mo; return t; } LL modular_exp(LL num,LL t,LL mo) { LL ret=1,temp=num%mo; for(;t;t>>=1,temp=modular_multi(temp,temp,mo)) if (t&1) ret=modular_multi(ret,temp,mo); return ret; } bool miller_rabbin(LL n) { if (n==2)return true; if (n<2||!(n&1))return false; int t=0; LL a,x,y,u=n-1; while((u&1)==0) t++,u>>=1; for(int i=0;i<S;i++) { a=rand()%(n-1)+1; x=modular_exp(a,u,n); for(int j=0;j<t;j++) { y=modular_multi(x,x,n); if (y==1&&x!=1&&x!=n-1) return false; ///其中用到定理,如果对模n存在1的非平凡平方根,则n是合数。 ///如果一个数x满足方程x^2≡1 (mod n),但x不等于对模n来说1的两个‘平凡’平方根:1或-1,则x是对模n来说1的非平凡平方根 x=y; } if (x!=1)///根据费马小定理,若n是素数,有a^(n-1)≡1(mod n).因此n不可能是素数 return false; } return true; } //分解质因数 #include<stdio.h> #include<math.h> int main() { int n,i; while(scanf("%d",&n)&&n) { for(i=2;i<=sqrt(n);i++) if(n%i==0&&(n/=i)) printf("%d ",i--); printf("%d/n",n); } return 0; } //斐波那契数列 int Fibonacci1(int n){ return n<=1?n:Fibonacci1(n-2)+Fibonacci1(n-1);} //组合数 //不取模 int Factorial(int n){ return !n?1:n*Factorial(n-1);} int Permutation(int n,int m){ return Factorial(n)/Factorial(n-m);} int Combination(int n,int m){ return Permutation(n,m)/Factorial(m);} int Repeated_Combination(int n,int m){ return Combination(n+m-1,m);} //取模 short c[1001][1001]; for (short i = 1; i <= 1000; i++) { c[i][i] = c[i][0] = 1; c[i][1] = c[i][i-1] = i; } for (short i = 2; i <= 1000; i++) { for (short j = 2; j < i; j++) { c[i][j] = (c[i-1][j-1] + c[i-1][j]) % 10007; } } //卢卡斯定理 /*C(n,m)%p=C(n%p,m%p)*C(n\p,m\p) 其中C(n\p,m\p)可以递归求解。 计算C(n%p,m%p),可先预处理出1!%p~(p-1)!%p,然后根据数据,考虑是同时预处理出1!的逆元、2!的逆元.....(p-1)!的逆元还是每次lucas算一遍逆元,x的逆元*y的逆元=x*y的逆元。逆元也可以线性筛(其实是近似线性),即用近似O(n)的时间求出1的逆元、2的逆元...(p-1)的逆元,然后阶乘的逆元=逆元的阶乘,即(p-1)!的逆元=1的逆元*2的逆元*....*(p-1)的逆元。 注意,在计算C时,若n<m则返回0,若m=0则返回1*/ void init() { int i; fac[0] =1; for(i =1; i <= p; i++) fac[i] = fac[i-1]*i % p; } long long C(long long n, long long m) { if(m > n) return 0; return fac[n]*pow(fac[m]*fac[n-m], p-2) % p; } long long Lucas(long long n, long long m) { if(m ==0) return 1; else return (C(n%p, m%p)*Lucas(n/p, m/p))%p; } //二项式定理 int Binomial_theorem(int n,int m){return Combination(m,n);} //卡特兰数 /* 令h(0)=1,h(1)=1,catalan数满足递推式[1]: h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2) 例如:h(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2 h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5 另类递推式[2] : h(n)=h(n-1)*(4*n-2)/(n+1); 递推关系的解为: h(n)=C(2n,n)/(n+1) (n=0,1,2,...) 递推关系的另类解为: h(n)=c(2n,n)-c(2n,n-1)(n=0,1,2,...) */ int Catalan(int n){ return Combination(2*n,n)/(n+1);} //汉诺塔 int Hanoi_number(int n){ return n==1?2:2*Hanoi_number(n-1)+2;}