更新日志
- 2018/10/4 绝大多数模板


// luogu-judger-enable-o2 #include<bits/stdc++.h> using namespace std; const int N=1000010; char s1[N],s2[N]; int nxt[N]; int len1,len2; void getnxt() { for(int i=1,j=0;i<len2;i++) { while(s2[i]!=s2[j]&&j) j=nxt[j]; if(s2[i]==s2[j]) nxt[i+1]=++j; else nxt[i+1]=0; } return; } int main() { scanf("%s",s1); scanf("%s",s2); len1=strlen(s1); len2=strlen(s2); getnxt(); for(int i=0,j=0;i<len1;i++) { while(s1[i]!=s2[j]&&j) j=nxt[j]; if(s1[i]==s2[j]) j++; if(j==len2) printf("%d\n",i+2-len2); } for(int i=1;i<=len2;i++) printf("%d ",nxt[i]); return 0; }


struct Trie { int nxt[26]; bool st; bool jud; }T[500010]; char s[51]; int n,m,cnt=1; namespace Trie_Tree { void insert() { int rt=1; for(int i=0;s[i];i++) { int tmp=s[i]-'a'; if(!T[rt].nxt[tmp]) T[rt].nxt[tmp]=++cnt; rt=T[rt].nxt[tmp]; } T[rt].jud=true; return; } int search() { int rt=1; for(int i=0;s[i];i++) { int tmp=s[i]-'a'; if(!T[rt].nxt[tmp]) return 0; rt=T[rt].nxt[tmp]; } if(!T[rt].jud) return 0; if(T[rt].st) return 2; T[rt].st=true; return 1; } } using namespace Trie_Tree;


// luogu-judger-enable-o2 #include<bits/stdc++.h> using namespace std; const int N=1000010; int n,len; char s[N]; struct Trie { int fail; int cnt; int nxt[26]; }T[N]; int cnt=0; void insert() { int rt=0; for(int i=0;i<len;i++) { int tmp=s[i]-'a'; if(!T[rt].nxt[tmp]) T[rt].nxt[tmp]=++cnt; rt=T[rt].nxt[tmp]; } T[rt].cnt++; return; } void BFS() { queue<int>q; for(int i=0;i<26;i++) { if(T[0].nxt[i]) { T[T[0].nxt[i]].fail=0; q.push(T[0].nxt[i]); } } while(!q.empty()) { int cur=q.front(); q.pop(); for(int i=0;i<26;i++) { if(T[cur].nxt[i]) { T[T[cur].nxt[i]].fail=T[T[cur].fail].nxt[i]; q.push(T[cur].nxt[i]); } else T[cur].nxt[i]=T[T[cur].fail].nxt[i]; } } } int query() { int rt=0,ans=0; for(int i=0;i<len;i++) { int tmp=s[i]-'a'; rt=T[rt].nxt[tmp]; for(int j=rt;j&&T[j].cnt!=-1;j=T[j].fail) { ans+=T[j].cnt; T[j].cnt=-1; } } return ans; } int main() { scanf("%d",&n); while(n--) { scanf("%s",s); len=strlen(s); insert(); } T[0].fail=0; BFS(); scanf("%s",s); len=strlen(s); printf("%d\n",query()); return 0; }


#include<bits/stdc++.h> #define N 51000010 using namespace std; int len,p[N],ans=1; char a[N],s[N<<1]; void manacher() { int maxright=0,mid; for(int i=1;i<len;i++) { if(i<maxright) p[i]=min(p[mid]+mid-i,p[mid*2-i]); else p[i]=1; for(;s[i+p[i]]==s[i-p[i]];p[i]++); if(p[i]+i>maxright) { mid=i; maxright=mid+p[i]; } } } void string_init() { s[0]=s[1]='#'; for(int i=0;i<len;i++) { s[i*2+2]=a[i]; s[i*2+3]='#'; } len=len*2+2; s[len]=0; } int main() { scanf("%s",a); len=strlen(a); string_init(); manacher(); for(int i=0;i<len;i++) ans=max(ans,p[i]); ans--; printf("%d\n",ans); return 0; }


// luogu-judger-enable-o2 #include<bits/stdc++.h> using namespace std; const int N=300010; long long ans; int len,p,cnt=1; char s[N]; namespace PAM { struct node { int nxt[26]; int fa,len,cnt; }T[N]; void Extend(int x) { int tmp=s[x]-'a'; while(s[x]!=s[x-T[p].len-1]) p=T[p].fa; if(!T[p].nxt[tmp]) { int k=T[p].fa; T[++cnt].len=T[p].len+2; while(s[x]!=s[x-T[k].len-1]) k=T[k].fa; T[cnt].fa=T[k].nxt[tmp]; T[p].nxt[tmp]=cnt; } p=T[p].nxt[tmp]; T[p].cnt++; } } using namespace PAM; int main() { scanf("%s",s+1); len=strlen(s+1); T[0].fa=1; T[1].fa=1; T[0].len=0; T[1].len=-1; for (int i=1;i<=len;i++) Extend(i); for (int i=cnt;i>1;i--) { long long tmp=1LL*T[i].cnt*T[i].len; if(tmp>ans) ans=tmp; T[T[i].fa].cnt+=T[i].cnt; } return printf("%lld\n",ans),0; }


// luogu-judger-enable-o2 #include<bits/stdc++.h> using namespace std; const int N=1000010; int SA[N],rank[N],height[N]; int x[N],y[N],bin[N]; int n,m=128; char s[N]; void getSA() { for(int i=1;i<=n;i++) bin[x[i]=s[i]-'0'+1]++; for(int i=1;i<=m;i++) bin[i]+=bin[i-1]; for(int i=n;i>=1;i--) SA[bin[x[i]]--]=i; for(int k=1;k<=n;k<<=1) { int tmp=0; for(int i=n-k+1;i<=n;i++) y[++tmp]=i; for(int i=1;i<=n;i++) if(SA[i]>=k+1) y[++tmp]=SA[i]-k; for(int i=1;i<=m;i++) bin[i]=0; for(int i=1;i<=n;i++) bin[x[y[i]]]++; for(int i=1;i<=m;i++) bin[i]+=bin[i-1]; for(int i=n;i>=1;i--) SA[bin[x[y[i]]]--]=y[i]; swap(x,y); tmp=0; for(int i=1;i<=n;i++) { if(y[SA[i]]!=y[SA[i-1]]) x[SA[i]]=++tmp; else if(y[SA[i]+k]!=y[SA[i-1]+k]) x[SA[i]]=++tmp; else x[SA[i]]=tmp; } if(tmp>=n) break; m=tmp; } for(int i=1;i<=n;i++) rank[SA[i]]=i; for(int i=1,tmp=0;i<=n;i++) { if(tmp) --tmp; while(s[i+tmp]==s[SA[rank[i]-1]+tmp]) ++tmp; height[rank[i]]=tmp; } } int main() { scanf("%s",s+1); n=strlen(s+1); getSA(); for(int i=1;i<=n;i++) printf("%d ",SA[i]); return puts(""),0; }


// luogu-judger-enable-o2 #include<bits/stdc++.h> using namespace std; const int MAXN=2000010; long long ans=0; char s[MAXN]; int a[MAXN],c[MAXN]; int len,size[MAXN]; int cnt=1,last=1; struct SAM_node { int nxt[26]; int fa,len; }T[MAXN<<1]; namespace SAM { void insert(int x) { int cur=last,np=++cnt; last=np; T[np].len=T[cur].len+1; for(;cur&&!T[cur].nxt[x];cur=T[cur].fa) { T[cur].nxt[x]=np; } if(!cur) { T[np].fa=1; } else { int q=T[cur].nxt[x]; if(T[cur].len+1==T[q].len) { T[np].fa=q; } else { int nq=++cnt; T[nq].len=T[cur].len+1; memcpy(T[nq].nxt,T[q].nxt,sizeof(T[q].nxt)); T[nq].fa=T[q].fa; T[q].fa=T[np].fa=nq; for(;T[cur].nxt[x]==q;cur=T[cur].fa) { T[cur].nxt[x]=nq; } } } size[np]=1; } void calc() { for(int i=1;i<=cnt;i++) { c[T[i].len]++; } for(int i=1;i<=cnt;i++) { c[i]+=c[i-1]; } for(int i=1;i<=cnt;i++) { a[c[T[i].len]--]=i; } for(int i=cnt;i;i--) { int cur=a[i]; size[T[cur].fa]+=size[cur]; if(size[cur]>1) { ans=max(ans,1LL*size[cur]*T[cur].len); } } printf("%lld\n",ans); return; } } using namespace SAM; int main() { scanf("%s",s+1); len=strlen(s+1); for(int i=1;i<=len;i++) insert(s[i]-'a'); calc(); return 0; }


int getmin() { int i=0,j=1,k=0,t; while(i<len && j<len && k<len) { t=s[(i+k)%len]-s[(j+k)%len]; if (!t) k++; else { if (t>0) i+=k+1; else j+=k+1; if (i==j) j++; k=0; } } return min(i,j); }


unsigned long long hash() { int len=strlen(s); unsigned long long ans=0; for (int i=0;i<len;i++) ans=(ans*base+(unsigned long long)s[i])%mod; return ans; }