各类模板

矩阵乘法

Matrix,支持二维 initializer_list 初始化。支持矩阵加法、矩阵乘法。重载 ++=**=

参考代码
struct Matrix{
	int n,m;
	int a[3][3];
	Matrix(int nn=-1,int mm=-1){
		if(mm==-1){
			mm=nn;
		}
		if(nn!=-1){
			n=nn,m=mm;
		}else{
			n=0,m=0;
		}
		memset(a,0,sizeof(a));
	}
	Matrix(initializer_list<initializer_list<int>> x){
		n=x.size();m=0;
		for(auto &i:x){
			m=max(m,(int)i.size());
		}
		int pi=0;
		for(auto &i:x){
			int pj=0;
			for(auto &j:i){
				a[pi][pj]=j;
				pj++;
			}
			pi++;
		}
	}
	int* operator [](const int &x){
		return a[x];
	}
	void unit(){
		memset(a,0,sizeof(a));
		for(int i=0;i<n;i++){
			a[i][i]=1;
		}
	} 
	void print(){
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				cout<<a[i][j]<<' ';
			}
			cout<<endl;
		}
	}
};
Matrix operator *(Matrix A,Matrix B){
	Matrix C(A.n,B.m);
	for(int i=0;i<A.n;i++){
		for(int j=0;j<B.m;j++){
			for(int k=0;k<A.m;k++){
				C[i][j]+=A[i][k]*B[k][j];
			}
		}
	}
	return C;
}
Matrix& operator *=(Matrix &A,Matrix B){
	return A=A*B;
}
Matrix operator +(Matrix A,Matrix B){
	Matrix C(A.n,A.m);
	for(int i=0;i<A.n;i++){
		for(int j=0;j<A.m;j++){
			C[i][j]=A[i][j]+B[i][j];
		} 
	} 
	return C;
}
Matrix& operator +=(Matrix &A,Matrix B){
	for(int i=0;i<A.n;i++){
		for(int j=0;j<A.m;j++){
			A[i][j]+=B[i][j];
		}
	}
	return A;
}

计数模板

参考代码
int fact[V+1],invFact[V+1];
int qpow(int base,int n){
	int ans=1;
	while(n){
		if(n&1){
			ans=1ll*ans*base%P;
		}
		base=1ll*base*base%P;
		n>>=1;
	}
	return ans;
}
void pre(){
	fact[0]=1;
	for(int i=1;i<=V;i++){
		fact[i]=1ll*fact[i-1]*i%P;
	}
	invFact[V]=qpow(fact[V],P-2);
	for(int i=V-1;0<=i;i--){
		invFact[i]=invFact[i+1]*(i+1ll)%P;
	}
}
int C(int n,int m){
	if(n<0||m<0||n<m){
		return 0;
	}
	return 1ll*fact[n]*invFact[m]%P*invFact[n-m]%P;
}

Barrett 约减

调用 Barrett.build(P) 更新模数为 P,调用 Barrett(x) 计算 x%P

支持 \(\left[-2^{63},2^{63}\right)\) 内的整数取模,模数范围为 \([2,2^{31})\)

参考代码
typedef long long ll;
typedef __int128 lll;
struct Barrett{
	ll p,m;
	inline void build(int P){
		p=P;
		m=((lll)1<<64)/p;
	}
	inline ll operator ()(ll x){
		ll ans=x-((lll)x*m>>64)*p;
		if(ans>=p){
			ans-=p;
		}
		return ans;
	}
}Barrett;

数据结构

并查集

参考代码
struct dsu{
	int f[N+1],size[N+1];
	
	int find(int x){
		if(f[x]!=x){
			return f[x]=find(f[x]);
		}
		return x;
	}
	void build(int n){
		for(int i=1;i<=n;i++){
			f[i]=i;
			size[i]=1;
		}
	}
	void merge(int x,int y){
		x=find(x),y=find(y);
		if(size[x]<size[y]){
			f[x]=y;
			size[y]+=size[x];
		}else{
			f[y]=x;
			size[x]+=size[y];
		}
	}
}dsu;

FHQ Treap

参考代码
mt19937 Rand(time(0));
constexpr const int N=1e5;
int root;
struct FHQTreap{
	int size;
	struct node{
		int value,size,rand;
		int lChild,rChild;
	}t[N+1];
	
	FHQTreap(){
		size=root=0;
	}
	int create(int x){
		t[++size]={x,1,Rand()};
		return size;
	}
	void up(int p){
		t[p].size=t[t[p].lChild].size+t[t[p].rChild].size+1;
	}
	void split(int p,int x,int &l,int &r){
		if(!p){
			l=r=0;
			return;
		}
		if(t[p].value<=x){
			l=p;
			split(t[p].rChild,x,t[p].rChild,r);
		}else{
			r=p;
			split(t[p].lChild,x,l,t[r].lChild);
		}
		up(p);
	}
	int merge(int l,int r){
		if(!l||!r){
			return l|r;
		}
		if(t[l].rand<t[r].rand){
			t[l].rChild=merge(t[l].rChild,r);
			up(l);
			return l;
		}else{
			t[r].lChild=merge(l,t[r].lChild);
			up(r);
			return r;
		}
	}
	void insert(int x){
		int l,r,p;
		split(root,x,l,r);
		root=merge(merge(l,create(x)),r);
	}
	void erase(int x){
		int l,r,p;
		split(root,x,l,r);
		split(l,x-1,l,p);
		p=merge(t[p].lChild,t[p].rChild);
		root=merge(merge(l,p),r);
	}
	int rank(int x){
		int l,r;
		split(root,x-1,l,r);
		int ans=t[l].size+1;
		root=merge(l,r); 
		return ans;
	}
	int kth(int k,int p=root){
		while(true){
			if(t[t[p].lChild].size+1==k){
				return t[p].value;
			}else if(t[t[p].lChild].size+1<k){
				k-=t[t[p].lChild].size+1;
				p=t[p].rChild;
			}else{
				p=t[p].lChild;
			}
		}
	}
	int prev(int x){
		int l,r;
		split(root,x-1,l,r);
		int ans=kth(t[l].size,l);
		root=merge(l,r);
		return ans;
	}
	int next(int x){
		int l,r;
		split(root,x,l,r);
		int ans=kth(1,r);
		root=merge(l,r);
		return ans;
	}
	
	void print(int p=root){
		if(!p){
			return;
		}
		print(t[p].lChild);
		cerr<<t[p].value<<' ';
		print(t[p].rChild);
	}
}t;

图论

链式前向星

参考代码
struct graph{
	struct edge{
		int v,r,w,c;
	}g[M<<2|1];
	
	int h[N+1],size=1;
	void create(int u,int v,int w,int c){
		g[++size]={v,h[u],w,c};
		h[u]=size;
	}
	
	edge& operator [](int x){
		return g[x];
	} 
}g;

Dijkstra

参考代码
void Dijkstra(int s,int dis[]){
	static bool vis[N+1];
	priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>q;
	memset(vis,0,sizeof(vis));
	fill(dis+1,dis+n+1,inf);
	dis[s]=0;
	q.push({dis[s],s});
	while(q.size()){
		int x=q.top().second;
		q.pop();
		if(vis[x]){
			continue;
		}
		vis[x]=true;
		for(auto [v,w]:g[x]){
			if(dis[x]+w<dis[v]){
				dis[v]=dis[x]+w;
				q.push({dis[v],v});
			}
		}
	}
}

SPFA

返回 \(1\) 表示无环,返回 \(0\) 表示有环。

参考代码
bool SPFA(int s,int dis[]){
	static bool in[N+1];
	static int c[N+1];
	fill(dis+1,dis+n+1,inf);
	queue<int>q;
	q.push(s);
	dis[s]=0;
	in[s]=true;
	while(q.size()){
		int x=q.front();q.pop();
		in[x]=false;
		if(c[x]>=n){
			return false;
		}
		for(auto [v,w]:g[x]){
			if(dis[x]+w<dis[v]){
				dis[v]=dis[x]+w;
				c[v]=c[x]+1;
				if(!in[v]){
					in[v]=true;
					q.push(v);
				}
			}
		}
	}
	return true;
}
posted @ 2025-08-16 20:02  TH911  阅读(22)  评论(0)    收藏  举报