模板集合2
前言 :记录学过的所有模板,有些比较远古还重新打了一遍。总需要留下点什么。按重要程度(主观)排序。CTRL+F 查找。很显然,有很多待补充的。(等我学到那再说吧)
数论
-
快速幂
int fpow(int a,int b) { int ans=1; while(b) { if(b&1) {ans*=a ;ans%=m ;} b>>=1 ; a=(a*a)%m; }return ans%m ; } -
欧拉筛
void getprime(int n) { no_prime[0]=no_prime[1]=1; for(int i=2;i<=n;i++) { if(no_prime[i]==0) prime.push_back(i) ; for(auto pj:prime) { if(pj*i>n) break ; no_prime[pj*i]=1 ; if(i%pj==1) break ; } } } -
组合数学
预处理
for(int i=0;i<=N;i++) for(int j=0;j<=i;j++) { if(j==0||j==i) c[i][j]=1; else c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod ; }直接计算
int C(int x,int y){ if(x<y||y<0)return 0; return f[x]*inv[y]%mod*inv[x-y]%mod; } -
分解质因数
void getprimefactor(int n){ for(int i=2;i*i<=n;i++){ int cnt=0; while(n%i==0) {cnt++;n/=i;} a[i]+=cnt; } if(n>1) a[n]++ ; } -
扩展欧几里得 (exgcd)
int exgcd(int a,int b,int &x,int &y) { if(b==0) {x=1,y=0 ;return a;} int g=exgcd(b,a%b,x,y) ; int t=x; x=y;y=t-a/b*y ; return g; } void sovle() { int a,b,c; cin >>a>>b>>c ; int g=__gcd(a,b) ; if(c%g!=0) {cout <<"-1\n";return ;} int x,y;exgcd(a,b,x,y) ; int x0=x*c/g,y0=y*c/g;//特解 int xmin=(x0%(b/g)+b/g)%(b/g) ,ymin=(y0%(a/g)+a/g)%(a/g) ;//最小解 if(xmin==0) xmin=b/g; if(ymin==0) ymin=a/g; int xmax=(c-b*ymin)/a, ymax=(c-a*xmin)/b;//最大解 int len=(xmax-xmin)/(b/g)+1 ;//个数 if(xmax<=0&&ymax<=0) {cout <<xmin <<" "<<ymin<<"\n" ;return;} cout <<len<<" "<<xmin<<" "<<ymin <<" "<<xmax<<" "<<ymax<<"\n"; } -
大步小步(BSGS)
\(b^l \equiv n \pmod p\) 给定b,n,p 求l
不保证p为质数int bsgs(int a,int b){ a%=mod;b%=mod; if(b==1)return 0; int m=ceil(sqrt(mod)); unordered_map<int,int>has; int t=b; for(int j=0;j<m;j++){ has[t]=j; t=t*a%mod; }//b*(a^j) int mi=fpow(a,m); t=1; //查a^{i*m}是否在map中 for(int i=1;i<=m;i++){ t=t*mi%mod; if(has.count(t)) return i*m-has[t] ; } return -1; }保证p为质数
int exbsgs(int a,int b,int p){ a%=p;b%=p; if(b==1||p==1) return 0; int d,k=0,aa=1; while(1){ d=__gcd(a,p) ; if(d==1) break; if(b%d!=0) return -1; k++ ;b/=d;p/=d; aa=aa*(a/d)%p; if(aa==b) return k; } int m=ceil(sqrt(p)) ; int t=b; unordered_map<int,int> mp; for(int i=0;i<m;i++) {mp[t]=i; t=t*a%p;} int mi=fpow(a,m,p) ; t=aa ; for(int i=1;i<=m;i++) { t=t*mi%p ; if(mp.count(t)) return i*m-mp[t]+k; } return -1; } -
Lucas定理
给定n ,m ,p\(C_{n + m}^n \bmod p\) 保证 \(p\) 为质数。
int Lucas(int n,int k,int mod) { if(k==0) return 1 ; return C(n%mod,k%mod)*Lucas(n/mod,k/mod,mod)%mod ; } -
欧拉函数
预处理
void getphi(int n) { phi[1]=1; for(int i=2;i<=n;i++) { if(no_prime[i]==0){ prime.push_back(i) ; phi[i]=i-1; } for(int j=0;j<(int)prime.size();j++) { int m=i*prime[j]; if(m>n) break ; no_prime[m]=1; if(i%prime[j]==0){ phi[m]=phi[i]*prime[j] ; break ; }phi[m]=phi[i]*phi[prime[j]] ; } } }直接求
int getphi(int x){ int ans=x; for(int i=2;i*i<=x;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 ; } -
错排问题
d[2]=1; d[3]=2; for(int i=4;i<=n;i++) d[i]=(i-1)*(d[i-1]+d[i-2])%mod ; -
威尔逊定理
题目:\(S_n=\Sigma_{k=1}^n\lfloor\frac{(x-1)!+1}{x}-\lfloor\frac{(x-1)!}{x}\rfloor\rfloor\)
定理:$(p-1)! \equiv -1 \pmod{p} $ p为质数
for(int i=1;i<=n;i++) { if(no_prime[i]==0) table[i]=table[i-1]+1; else table[i]=table[i-1] ; }
其余杂板
-
并查集
void init(int n){for(int i=1;i<=n;i++) fa[i]=i;} int fid(int x) {if(fa[x]!=x)fa[x]=fid(fa[x]); return fa[x];} void unio(int x,int y) {int fax=fid(x) ,fay=fid(y) ;if(fax!=fay) fa[fay]=fax ;} -
ST表
void init(int n) { for(int i=2;i<=n;i++) lg[i]=lg[i/2]+1 ; for(int i=1;i<=20;i++) for(int j=1;j+(1<<i)-1<=n;j++) st[i][j]=max(st[i-1][j],st[i-1][j+(1<<(i-1))]) ; } int RMQ(int l,int r) { int k=lg[r-l+1] ; return max(st[k][l],st[k][r-(1<<k)+1]) ; } -
单调栈
while(tot>0&&a[stk[tot]]<=a[i]) tot-- ; ans[i]=tot?stk[tot]:0 ; stk[++tot]=i ; -
单调队列
int q[N],head=0,tail=-1; for(int i=1;i<=n+1;i++) { while(head<=tail&&i-q[head]>m) head++; while(head<=tail&&a[q[tail]]<a[i]) tail--; q[++tail]=i; } -
线性基
#include <bits/stdc++.h> #define int long long using namespace std ; const int N=55 ; int a[N],xxj[N] ; signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0) ; int n; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i] ; for(int lg=49;lg>=0;lg--) if((a[i]>>lg)&1) { if(xxj[lg]>0) a[i]^=xxj[lg] ; else {xxj[lg]=a[i] ;break ;} } } int ans=0 ; for(int lg=49;lg>=0;lg--) if(((ans>>lg)&1)==0) ans^=xxj[lg] ; cout<<ans ; return 0; } -
矩阵 (矩阵乘 & 矩阵快速幂)
struct Matrix{ int matrix[110][110] ,n,m; Matrix(int nn,int mm) {n=nn; m=mm; memset(matrix,0,sizeof(matrix)) ; return ;} int *operator[](int i) {return matrix[i] ;} void init() { memset(matrix,0,sizeof(matrix)) ; for(int i=1;i<=n;i++) matrix[i][i]=1; } void print() { for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++) cout<<matrix[i][j]<<' ' ; cout<<"\n" ; } } }; Matrix operator +(Matrix a,Matrix b) { for(int i=1;i<=a.n;i++) for(int j=1;j<=a.m;j++) a[i][j]+=b[i][j]; return a ; } Matrix operator *(Matrix &a,Matrix &b) { Matrix c(a.n,b.m) ; for(int i=1;i<=a.n;i++) for(int j=1;j<=b.m;j++) for(int l=1;l<=a.m;l++) (c[i][j]+=a[i][l]*b[l][j]%mod)%=mod; return c; } Matrix operator %(Matrix a,int mod) { for(int i=1;i<=a.n;i++) for(int j=1;j<=a.m;j++) a[i][j]%=mod; return a; } Matrix operator ^(Matrix a,int b) { Matrix c(a.n,a.m) ; c.init() ; while(b) { if(b&1) c=c*a%mod; a=a*a%mod; b>>=1; } return c; } -
高精度 (+-*)
#include <bits/stdc++.h> //#define int long long using namespace std ; const int N=2e4+100 ; struct SuperInt { int d[N],lenth ; int& operator[](int i) {return d[i] ;} SuperInt(){memset(d,0,sizeof(d)); lenth=1;} void print() {for(int i=lenth;i>=1;i--) cout<<d[i];} void init(string s) { lenth=s.size() ; for(int i=1;i<=lenth;i++) d[i]=s[lenth-i]-'0' ; } void fixadd() { for(int i=1;i<lenth;i++) {d[i+1]+=d[i]/10;d[i]%=10;} while(d[lenth]>=10) { d[lenth+1]+=d[lenth]/10 ; d[lenth]%=10; lenth++; } } void fixsub() { for(int i=1;i<lenth;i++) if(d[i]<0) {d[i]+=10; d[i+1]--;} while(d[lenth]<0) { d[lenth+1]--; d[lenth]+=10; lenth++; } } }; SuperInt operator +(SuperInt &a,SuperInt &b) { SuperInt rslt; int i; for(i=1;i<=a.lenth||i<=b.lenth;i++) rslt[i]=a[i]+b[i] ; rslt.lenth=i-1; rslt.fixadd() ; return rslt ; } SuperInt operator -(SuperInt &a,SuperInt &b) { SuperInt rslt; int i; for(i=1;i<=a.lenth||i<=b.lenth;i++) rslt[i]=a[i]-b[i] ; rslt.lenth=i-1;rslt.fixsub() ; while(rslt.lenth>1&&rslt[rslt.lenth]==0) rslt.lenth--; return rslt ; } SuperInt operator *(SuperInt &a,SuperInt &b) { SuperInt rslt; for(int i=1;i<=a.lenth;i++){ for(int j=1;j<=b.lenth;j++) { rslt[i+j-1]+=a[i]*b[j] ; } } rslt.lenth=max(a.lenth,b.lenth)+1; rslt.fixadd() ; while(rslt.lenth>1&&rslt[rslt.lenth]==0) rslt.lenth--; return rslt ; } bool operator <(SuperInt &a,SuperInt &b) { if(a.lenth!=b.lenth) return a.lenth<b.lenth ; for(int i=a.lenth;i>=1;i--) if(a[i]!=b[i]) return a[i]<b[i]; return 0; } signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0) ; SuperInt a,b;string s1,s2; cin>>s1>>s2 ; a.init(s1); b.init(s2) ; if(a.lenth<b.lenth) swap(a,b) ; SuperInt c=a*b; c.print() ; return 0; }

浙公网安备 33010602011771号