模板集合2

一个模板集合实在是太卡了,再开一个吧

字符串

字符串是算法竞赛高频基础模块,常用于字符串匹配、去重、回文判定、文本处理等题型。

  • 字符串hash

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    const int mod=5e4+3 ,N=5e4+10;
    int a[N] ; int b=133 ;
    struct HashNode{string date;} h[mod+10];
    int has(string s) {
    	int p=0;
    	for(int i=0;i<(int)s.size();i++) p=(p*b+s[i])%mod; 
    	while(h[p].date.size()>0&&h[p].date!=s) p++ ;
    	return p;
    }
    int ans=0;
    void sovle() {
    	string s; cin>>s; 
    	int p=has(s) ;
    	if(h[p].date!=s) {h[p].date=s;ans++; }
    }
    signed main() { 
    	ios::sync_with_stdio(0);cin.tie(0); cout.tie(0) ;
    	int T; cin>>T; while(T--) sovle() ;
    	cout<<ans ;
    	return 0;
    }
    
  • 马拉车manacher

    #include <bits/stdc++.h> 
    //#define int long long 
    using namespace std ;
    const int N=22*1e6+10 ;
    int p[N] ; //p_i表示以i为对称中心,能拓展的回文数量
    signed main() {
    	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0) ;
    	string s; char c; 
    	while(cin>>c) {s+=c; s+="#" ;}
    	s=" #"+s ;
    	
    	int l=0,r=1,ans=0 ;
    	for(int i=1;i<=(int)s.size();i++) {
    		p[i]=r>i?min(r-i,p[l+r-i]):1 ;
    		while(s[i-p[i]]==s[i+p[i]]) p[i]++ ;
    		ans=max(ans,(p[i]*2-1)/2) ;
    		if(p[i]+i>r) {l=i-p[i] ; r=i+p[i] ;}
    	}
    	
    	cout<<ans ;
    	return 0 ;
    }
    
  • KMP

    朴素KMP

    void init(string t) {
    	for(rg int i=1,j=0;i<(int)t.size();i++) {
    		while(j>0&&t[i]!=t[j]) j=p[j-1] ;
    		j+=(t[i]==t[j]) ;
    		p[i]=j ; 
    	}
    }
    
    void KMP() {
    	for(rg int i=0,j=0;i<(int)s.size();) {
    		if(s[i]==t[j]) {i++; j++;}
    		else if(j>0) j=p[j-1] ;
    		else i++ ;
    		if(j==(int)t.size()) {
    			j=p[j-1] ;
    			cout<<i-t.size()+1<<'\n' ;
    		}
    	}
    }
    

    扩展KMP / exKMP

    inline void Zfunction() {
    	z[0]=n ;
    	for(rg int i=1,l=0,r=0;i<n;i++) {
    		if(i<=r) z[i]=min(r-i+1,z[i-l]) ;
    		while(i+z[i]<n&&t[z[i]]==t[i+z[i]]) z[i]++ ;
    		if(i+z[i]-1>r) {l=i; r=i+z[i]-1;}
    	}
    }
    
    inline void exKMP() {
    	for(rg int i=0,l=0,r=-1;i<m;i++) {
    		if(i<=r) p[i]=min(r-i+1,z[i-l]) ;
    		while(i+p[i]<m&&p[i]<n&&s[i+p[i]]==t[p[i]]) p[i]++ ;
    		if(i+p[i]-1>r) {l=i; r=i+p[i]-1;}
    	}
    }
    
  • 失配树 (KMP树)

    inline void init() {
    	lg[1]=0 ;
    	for(rg int i=2;i<=n;i++) lg[i]=lg[i/2]+1;
    	for(rg int i=1,j=0;i<(int)s.size();i++) {
    		while(j>0&&s[i]!=s[j]) j=p[j-1] ;
    		if(s[i]==s[j]) j++ ;
    		p[i]=j ;
    	}
    	for(rg int i=1;i<=n;i++) g[p[i-1]].push_back(i) ;
    }
    
    inline void dfs(int u,int f) {
    	fa[u][0]=f ; dep[u]=dep[f]+1 ;
    	for(rg int i=1;i<=20;i++) fa[u][i]=fa[fa[u][i-1]][i-1] ;
    	for(auto v:g[u]) if(v!=f) dfs(v,u) ;
    }
    
    inline int lca(int u,int v) {
    	if(dep[u]<dep[v]) swap(u,v) ;
    	while(dep[u]>dep[v]) {
    		int k=lg[dep[u]-dep[v]] ;
    		u=fa[u][k] ;
    	}
    	if(u==v) return u ;
    	for(rg int k=lg[dep[u]];k>=0;k--) 
    		if(fa[u][k]!=fa[v][k]) {u=fa[u][k]; v=fa[v][k] ;}
    	return fa[u][0] ;
    }
    
    inline int query(int u,int v) {int f=lca(u,v);return (f==u?fa[u][0]:f);} 
    
  • KMP自动机

    inline void build(){
    	m=t.size()-1;
    	for(rg int i=2,j=0;i<=m;i++){
    		while(j&&t[i]!=t[j+1]) j=fail[j];
    		if(t[i]==t[j+1]) j++;
    		fail[i]=j;
    	}
    	for(rg int c=0;c<26;c++) tire[0][c]=(t[1]==(char)('a'+c))?1:0;
    	for(rg int i=1;i<=m;i++){
    		for(rg int c=0;c<26;c++){
    			char ch=(char)('a'+c);
    			if(i<m&&t[i+1]==ch) tire[i][c]=i+1;
    			else tire[i][c]=tire[fail[i]][c];
    		}
    	}
    }
    inline void match(string s){
    	for(rg int i=0,j=0;i<(int)s.size();i++) {
    		int c=s[i]-'a';
    		j=tire[j][c];
    		if(j==m) j=tire[j][c];
    	}
    }
    inline void add(char c){
    	t+=c;m++;
    	int j=fail[m-1];
    	while(j&&t[m]!=t[j+1]) j=fail[j];
    	if(t[m]==t[j+1]) j++;
    	fail[m]=j;
    	for(rg int c=0;c<M;c++) tire[m][c]=tire[fail[m]][c];
    	tire[m-1][t[m]-'a']=m;
    }
    
  • AC自动机

    inline void insert(string s,int pos) {
    	int p=0 ;
    	for(rg int i=0;i<(int)s.size();i++) {
    		int c=s[i]-'a' ;
    		if(tire[p][c]==0) tire[p][c]=++tot ;
    		p=tire[p][c] ;
    	}
    	g[p].emplace_back(pos) ;
    }
    
    inline void build() {
    	queue<int> q ;
    	for(rg int i=0;i<26;i++) if(tire[0][i]!=0)
    		q.emplace(tire[0][i]) ;
    	while(!q.empty()) {
    		int u=q.front(); q.pop() ;
    		for(rg int i=0,v=tire[u][i];i<26;i++,v=tire[u][i]) {
    			if(v!=0) {
    				fail[v]=tire[fail[u]][i] ;
    				q.emplace(v) ;
    			}
    			else tire[u][i]=tire[fail[u]][i] ;
    		}
    	}
    }
    
    inline void search(string s) {
    	int p=0 ;
    	for(rg int i=0;i<(int)s.size();i++) {
    		int c=s[i]-'a' ;
    		cnt[p=tire[p][c]] ++ ;
    	}
    }
    
    inline void Toposort() { //最后统计答案,因题而异
    	queue<int> q ;
    	for(rg int i=1;i<=tot;i++) du[fail[i]]++ ;
    	
    	for(rg int i=1;i<=tot;i++) if(du[i]==0) q.emplace(i) ;
    	while(!q.empty()) {
    		int u=q.front(); q.pop() ;
    		cnt[fail[u]]+=cnt[u] ;
    		du[fail[u]]-- ;
    		if(du[fail[u]]==0) q.emplace(fail[u]) ;
    	}
    	
    	for(rg int i=1;i<=tot;i++) for(auto j:g[i]) ans[j]+=cnt[i] ; 
    }
    
  • 回文自动机 (PAM)

    inline int addnode(int u) {
    	len[++tot]=u ;
    	fail[tot]=cnt[tot]=0 ;
    	memset(tire[tot],0,sizeof(tire[tot])) ;
    	return tot ;
    }
    
    inline void init() {
    	tot=-1; n=last=0 ;s[0]='#' ;
    	addnode(0); addnode(-1) ;
    	fail[0]=1 ;
    }
    
    inline int getfail(int u) {
    	while(s[n-len[u]-1]!=s[n]) u=fail[u] ;
    	return u ;
    }
    
    inline int insert(char ch,int c=0) {
    	s[++n]=ch ; c=ch-'a' ;
    	int u=getfail(last) ;
    	if(!tire[u][c]) {
    		int v=addnode(len[u]+2) ;
    		fail[v]=tire[getfail(fail[u])][c] ;
    		tire[u][c]=v ;
    	}
    	last=tire[u][c] ;
    	return cnt[last]=cnt[fail[last]]+1 ;
    }
    

其余杂板

其实是我能力不行,不知道其属于哪类 如果有更细的分类请联系我修改,谢谢。

  • 并查集

    朴素并查集 \(O(nlogn)\)

    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 ;}
    

    按秩合并 (启发式合并) \(O(n\alpha(n))\) 此处\(\alpha\)可视为常数

    void init() {for(rg int i=1;i<=n;i++) {fa[i]=i;siz[i]=1;}sc=n ;}
    int fid(int x) {return fa[x]==x?fa[x]:fa[x]=fid(fa[x]) ;}
    void unio(int x,int y) {
    	int fax=fid(x),fay=fid(y) ;
    	if(fay==fax) return ;
    	if(siz[fax]<siz[fay]) swap(fax,fay) ;
    	fa[fay]=fax ;siz[fax]+=siz[fay] ;
    	sc--;//联通块个数
    }
    
  • 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;
    }
    
  • 三维偏序 (CDQ分治)

    #include <bits/stdc++.h>
    //#define int long long
    #define rg register 
    #define lowbit(x) ((-(x))&(x))
    #define mid ((l+r)>>1)
    using namespace std;
    
    bool M1 ;
    const int N=1e5+10 ;
    struct node{
    	int a,b,c,cnt,ans; 
    	bool operator ==(const node &x) const{return a==x.a&&b==x.b&&c==x.c ;}
    }arr[N];
    bool cmpmain(const node &x,const node &y) {return x.a!=y.a?x.a<y.a:x.b!=y.b?x.b<y.b:x.c<y.c ;}
    bool cmpcdq(const node&x,const node&y) {return x.b<y.b;}
    int tr[N*2],ans[N];
    void modify(int i,int add) {for(;i<=2e5;i+=lowbit(i)) tr[i]+=add ;}
    int query(int i,int res=0) {for(;i;i-=lowbit(i)) res+=tr[i] ;return res;}
    bool M2 ;
    
    void cdqsovle(int l,int r) {
    	if(l==r) return ;
    	cdqsovle(l,mid) ; cdqsovle(mid+1,r) ;
    	
    	sort(arr+l,arr+mid+1,cmpcdq) ;
    	sort(arr+mid+1,arr+r+1,cmpcdq) ;
    	
    	int i=l ;
    	for(rg int j=mid+1;j<=r;j++) {
    		while(i<=mid&&arr[i].b<=arr[j].b) modify(arr[i].c,arr[i].cnt) ,i++;
    		arr[j].ans+=query(arr[j].c) ;
    	}
    	
    	for(rg int k=l;k<i;k++) modify(arr[k].c,-arr[k].cnt) ;
    }
    
    signed main() { 
    	cerr<<"This program has used"<<abs(M1-M2)/1024/1024<<"MB\n\n" ;
    	
    	int n,k; cin>>n; cin>>k ;
    	for(rg int i=1,a,b,c;i<=n;i++) {cin>>a; cin>>b; cin>>c ;arr[i]={a,b,c,1,0} ;}
    	sort(arr+1,arr+n+1,cmpmain) ;
    	
    	for(rg int i=1;i<=n;) {
    		int j=i; 
    		while(j<=n&&arr[i]==arr[j]) j++ ;
    		for(int k=i,cnt=j-i;k<j;k++) arr[k].cnt=cnt ;
    		i=j ;
    	}
    	int m=unique(arr+1,arr+1+n)-arr-1; 
    	cdqsovle(1,m) ;
    	
    	for(rg int i=1;i<=m;i++) {
    		int rel=arr[i].ans+arr[i].cnt-1 ;
    		ans[rel]+=arr[i].cnt ;
    	}
    	for(rg int i=0;i<n;i++) cout<<ans[i]<<"\n" ;
    	
    	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-09-01 08:41  Emumumu  阅读(9)  评论(0)    收藏  举报