模板集合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;
    } 
    
posted @ 2026-07-17 10:23  _Emu  阅读(6)  评论(0)    收藏  举报