模板集合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; }

浙公网安备 33010602011771号