挂链式hash:https://www.luogu.org/problemnew/show/P3823
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ull; const int N=5e5+7,p=19260817,mod=998244353,gloid=(1<<24)-1; int n,m,q,a[N],pre[N],nxt[N],cnt[N],f[150]; ull h[150],pw[150]; char s[11000000]; struct Hash{ struct edge{ull x;int v,nxt;}e[21000000]; int hd[gloid+1],ecnt; void add(ull x,int d) { int u=x&gloid; for(int i=hd[u];i;i=e[i].nxt)if(e[i].x==x){e[i].v+=d;return;} e[++ecnt]=(edge){x,d,hd[u]},hd[u]=ecnt; } int query(ull x) { int u=x&gloid; for(int i=hd[u];i;i=e[i].nxt)if(e[i].x==x)return e[i].v; return 0; } }mp; void merge() { int x,y,L=51,R=50;scanf("%d%d",&x,&y); memset(f,0,sizeof f); for(int i=x;i&&L>1;i=pre[i])f[--L]=a[i]; for(int i=y;i&&R<100;i=nxt[i])f[++R]=a[i]; for(int i=1;i<=R;i++)h[i]=h[i-1]*p+f[i]; for(int i=L;i<=50;i++) for(int j=51;j<=min(R,i+49);j++) mp.add(h[j]-h[i-1]*pw[j-i+1],1); nxt[x]=y,pre[y]=x; } void split() { int x,y,L=51,R=50;scanf("%d",&x),y=nxt[x]; memset(f,0,sizeof f); for(int i=x;i&&L>1;i=pre[i])f[--L]=a[i]; for(int i=y;i&&R<100;i=nxt[i])f[++R]=a[i]; for(int i=1;i<=R;i++)h[i]=h[i-1]*p+f[i]; for(int i=L;i<=50;i++) for(int j=51;j<=min(R,i+49);j++) mp.add(h[j]-h[i-1]*pw[j-i+1],-1); nxt[x]=pre[y]=0; } int query() { scanf("%s",s+1); int len=strlen(s+1),ret=1,k; scanf("%d",&k); ull val=0; if(k==1) { for(int i=1;i<=len;i++)ret=1ll*ret*cnt[s[i]]%mod; return ret; } for(int i=1;i<=len;i++) { val=val*p+s[i]; if(i>k)val-=pw[k]*s[i-k]; if(i>=k)ret=1ll*ret*mp.query(val)%mod; } return ret; } int main() { scanf("%d%d",&n,&q); pw[0]=1;for(int i=1;i<=50;i++)pw[i]=pw[i-1]*p; for(int i=1;i<=n;i++)scanf("%d",&a[i]),a[i]+='0',cnt[a[i]]++; while(q--) { int op;scanf("%d",&op); if(op==1)merge(); else if(op==2)split(); else printf("%d ",query()); } }
最小表示法:https://www.luogu.org/problemnew/show/P1368
#include<bits/stdc++.h> using namespace std; const int N=6e5+7; int n,a[N]; int solve() { int i=1,j=2; while(i<=n&&j<=n) { int k=0; while(j+k<=2*n&&a[i+k]==a[j+k])k++; if(j+k>2*n)break; if(a[i+k]>a[j+k])i=max(j,i+k+1),j=i+1; else j+=k+1; } return min(i,j); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]),a[i+n]=a[i]; int pos=solve(); for(int i=pos;i<pos+n;i++)printf("%d ",a[i]); }
KMP:https://www.luogu.org/problemnew/show/P3375
#include<cstdio> #include<cstring> using namespace std; const int N=1e6+7; int n,m,nxt[N]; char s1[N],s2[N]; void getnxt() { nxt[0]=-1; for(int i=1,j=-1;i<=m;i++) { while(j!=-1&&s2[i]!=s2[j+1])j=nxt[j]; nxt[i]=++j; } } void kmp() { for(int i=1,j=0;i<=n;i++) { while(j&&s1[i]!=s2[j+1])j=nxt[j]; if(s1[i]==s2[j+1])j++; if(j==m)printf("%d ",i-m+1),j=nxt[j]; } } int main() { scanf("%s%s",s1+1,s2+1); n=strlen(s1+1),m=strlen(s2+1); getnxt(),kmp(); for(int i=1;i<=m;i++)printf("%d ",nxt[i]); }
Trie(异或粽子)
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; typedef long long ll; const int N=5e5+7; struct node{int u,id;ll v;}; int n,k,tot=1,ch[N*33][2],sz[N*33]; ll ans,a[N]; bool operator<(node a,node b){return a.v<b.v;} priority_queue<node>q; void build(ll x) { int u=1; for(int i=31;i>=0;i--) { int idx; if(x&(1ll<<i))idx=1;else idx=0; if(!ch[u][idx])ch[u][idx]=++tot; u=ch[u][idx]; sz[u]++; } } ll query(ll x,int rk) { int u=1; ll ret=0; for(int i=31;i>=0;i--) { int idx; if(x&(1ll<<i))idx=1;else idx=0; if(sz[ch[u][idx^1]]>=rk)ret+=1ll<<i,u=ch[u][idx^1]; else rk-=sz[ch[u][idx^1]],u=ch[u][idx]; } return ret; } int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[i]^=a[i-1]; for(int i=0;i<=n;i++)build(a[i]); for(int i=0;i<=n;i++)q.push((node){i,1,query(a[i],1)}); for(int tim=1;tim<2*k;tim++) { node u=q.top();q.pop(); if(tim&1)ans+=u.v; if(u.id==n)continue; u.id++,u.v=query(a[u.u],u.id); q.push(u); } printf("%lld",ans); return 0; }
AC自动机:https://www.luogu.org/problemnew/show/P5357
#include<bits/stdc++.h> using namespace std; const int N=2e5+7; int n,tot,qs,qe,q[N],d[N],ans[N],hd[N],nxt[N],ch[N][26],fail[N]; char str[N*10]; void insert(int id) { int u=0,len=strlen(str+1); for(int i=1;i<=len;i++) { if(!ch[u][str[i]-'a'])ch[u][str[i]-'a']=++tot; u=ch[u][str[i]-'a']; } nxt[id]=hd[u],hd[u]=id; } void build() { qs=1,qe=0; for(int i=0;i<26;i++)if(ch[0][i])q[++qe]=ch[0][i]; while(qs<=qe) { int u=q[qs++]; for(int i=0;i<26;i++) if(ch[u][i])fail[ch[u][i]]=ch[fail[u]][i],q[++qe]=ch[u][i]; else ch[u][i]=ch[fail[u]][i]; } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%s",str+1),insert(i); build(); scanf("%s",str+1); int u=0,len=strlen(str+1); for(int i=1;i<=len;i++)u=ch[u][str[i]-'a'],d[u]++; for(int i=tot;i;i--) { for(int j=hd[q[i]];j;j=nxt[j])ans[j]=d[q[i]]; d[fail[q[i]]]+=d[q[i]]; } for(int i=1;i<=n;i++)printf("%d ",ans[i]); }
fail树:https://www.lydsy.com/JudgeOnline/problem.php?id=3172
#include<cstdio> #include<iostream> #include<string.h> #include<queue> using namespace std; const int N=1e6+100; int n,sz,ch[N][26],fail[N],q[N],ans[N],pos[220]; char str[N]; void insert(int k) { int len=strlen(str),u=0; for(int i=0;i<len;i++) { if(!ch[u][str[i]-'a'])ch[u][str[i]-'a']=sz++; u=ch[u][str[i]-'a'],ans[u]++; } pos[k]=u; } void build() { int qs=0,qe=0; for(int i=0;i<26;i++)if(ch[0][i])fail[ch[0][i]]=0,q[qe++]=ch[0][i]; while(qs<qe) { int u=q[qs++]; for(int i=0;i<26;i++) if(ch[u][i]) { int v=fail[u]; while(v&&!ch[v][i])v=fail[v]; fail[ch[u][i]]=ch[v][i]; q[qe++]=ch[u][i]; } } while(qe--)ans[fail[q[qe]]]+=ans[q[qe]]; } int main() { scanf("%d",&n); sz=1; for(int i=1;i<=n;i++)scanf("%s",str),insert(i); build(); for(int i=1;i<=n;i++)printf("%d ",ans[pos[i]]); }
manacher:https://www.luogu.org/problemnew/show/P3805
#include<bits/stdc++.h> using namespace std; const int N=22222222; char s[N],a[N]; int n,l[N]; void manacher() { int mx=0,po=0; for(int i=1;i<n;i++) { l[i]=mx>i?min(mx-i,l[2*po-i]):1; while(s[i-l[i]]==s[i+l[i]])l[i]++; if(l[i]+i>mx)mx=l[i]+i,po=i; } } int main() { scanf("%s",a),n=strlen(a); s[0]=s[1]='#'; for(int i=0;i<n;i++)s[i*2+2]=a[i],s[i*2+3]='#'; s[n=n*2+2]=0; manacher(); int ans=0; for(int i=0;i<n;i++)ans=max(ans,l[i]); printf("%d",ans-1); }
#include<bits/stdc++.h> using namespace std; const int N=1e5+99; char s[N]; int n,m=26,a[N],x[N],y[N],b[N],sa[N],rnk[N],height[N]; bool cmp(int i,int j,int l){return y[i]==y[j]&&(i+l>n?-1:y[i+l])==(j+l>n?-1:y[j+l]);} void getsa() { memset(b,0,sizeof b); int p,j,k; for(int i=1;i<=n;i++)b[x[i]=a[i]]++; for(int i=1;i<=m;i++)b[i]+=b[i-1]; for(int i=n;i>=1;i--)sa[b[x[i]]--]=i; for(k=1;k<=n;k*=2) { p=0; for(int i=n-k+1;i<=n;i++)y[++p]=i; for(int i=1;i<=n;i++)if(sa[i]>k)y[++p]=sa[i]-k; memset(b,0,sizeof b); for(int i=1;i<=n;i++)b[x[y[i]]]++; for(int i=1;i<=m;i++)b[i]+=b[i-1]; for(int i=n;i>=1;i--)sa[b[x[y[i]]]--]=y[i]; swap(x,y); p=1;x[sa[1]]=1; for(int i=2;i<=n;i++)x[sa[i]]=cmp(sa[i-1],sa[i],k)?p:++p; if(p==n)break; m=p; } p=k=0; for(int i=1;i<=n;i++)rnk[sa[i]]=i; for(int i=1;i<=n;height[rnk[i++]]=k) { if(k)k--; j=sa[rnk[i]-1]; while(s[i+k]==s[j+k])k++; } } int main() { scanf("%s",s+1);n=strlen(s+1); for(int i=1;i<=n;i++)a[i]=s[i]-'a'+1; getsa(); for(int i=1;i<=n;i++)printf("%d ",sa[i]);printf(" "); for(int i=2;i<=n;i++)printf("%d ",height[i]); }
SAM:https://www.luogu.org/problemnew/show/P3804
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e6+7; int n,lst=1,cnt=1,len[N],ch[N][26],fa[N],sz[N],a[N],b[N]; ll ans; char str[N]; void build(int x) { int p=lst,np=++cnt; len[np]=len[p]+1; while(p&&!ch[p][x])ch[p][x]=np,p=fa[p]; if(!p)fa[np]=1; else{ int q=ch[p][x]; if(len[p]+1==len[q])fa[np]=q; else{ int nq=++cnt; memcpy(ch[nq],ch[q],sizeof ch[q]); fa[nq]=fa[q],fa[q]=fa[np]=nq,len[nq]=len[p]+1; while(p&&ch[p][x]==q)ch[p][x]=nq,p=fa[p]; } } sz[lst=np]=1; } int main() { scanf("%s",str+1),n=strlen(str+1); for(int i=1;i<=n;i++)build(str[i]-'a'); for(int i=1;i<=cnt;i++)b[len[i]]++; for(int i=1;i<=cnt;i++)b[i]+=b[i-1]; for(int i=1;i<=cnt;i++)a[b[len[i]]--]=i; for(int i=cnt;i;i--) { int now=a[i]; sz[fa[now]]+=sz[now]; if(sz[now]>1)ans=max(ans,1ll*sz[now]*len[now]); } cout<<ans; }
PAM:CF906E
#include<bits/stdc++.h> using namespace std; #define mp make_pair typedef long long ll; const int N=1e6+7; int n,tot,s[N],ch[N][26],len[N],fa[N],tran[N],d[N]; char S[N]; pair<int,int>f[N],g[N]; int extend(int n,int p,char c) { int idx=c-'a'; while(s[n-len[p]-1]!=c)p=fa[p]; if(!ch[p][idx]) { int q=++tot,t=fa[p]; len[q]=len[p]+2; while(s[n-len[t]-1]!=c)t=fa[t]; fa[q]=ch[t][idx],ch[p][idx]=q,d[q]=len[q]-len[fa[q]]; tran[q]=d[q]==d[fa[q]]?tran[fa[q]]:fa[q]; } return ch[p][idx]; } int main() { fa[0]=tot=1,len[1]=-1; scanf("%s",S+1),n=strlen(S+1);for(int i=1;i<=n;i++)s[(i<<1)-1]=S[i]; scanf("%s",S+1);for(int i=1;i<=n;i++)s[i<<1]=S[i]; n=n<<1; int st=0; for(int i=1;i<=n;i++) { f[i]=mp(1e9,-1); st=extend(i,st,s[i]); for(int p=st;p;p=tran[p]) { int lst=i-len[tran[p]]-d[p]; g[p]=mp(f[lst].first,lst); if(d[fa[p]]==d[p])g[p]=min(g[p],g[fa[p]]); if(i%2==0)f[i]=min(f[i],mp(g[p].first+1,g[p].second)); } if(i%2==0&&s[i]==s[i-1])f[i]=min(f[i],mp(f[i-2].first,i-2)); } if(f[n].first>n)puts("-1"); else{ printf("%d ",f[n].first); int p=n; while(p) { if(p-f[p].second!=2)printf("%d %d ",f[p].second/2+1,(p+1)/2); p=f[p].second; } } }
完结撒花