jiangly版本的Manachar
std::vector<int> manacher(std::string s) {
std::string t = "#";
for (auto c : s) {
t += c;
t += '#';
}
int n = t.size();
std::vector<int> r(n);
for (int i = 0, j = 0; i < n; i++) {
if (2 * j - i >= 0 && j + r[j] > i) {
r[i] = std::min(r[2 * j - i], j + r[j] - i);
}
while (i - r[i] >= 0 && i + r[i] < n && t[i - r[i]] == t[i + r[i]]) {
r[i] += 1;
}
if (i + r[i] > j + r[j]) {
j = i;
}
}
return r;
}
Manacher
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2.2e7+7;
int d[N];
void manacher(string s)
{
int l=0,r=0;
d[0]=1;
for(int i=1; i<s.size(); i++)
{
int k=(i>r)?1:min(d[l+r-i],r-i+1);
while(s[i-k]==s[i+k]) k++;
d[i]=k;
k--;
if(i+k>r)
{
l=i-k; r=i+k;
}
}
}
void O_o()
{
string t,s="";
cin>>t;
s+="&";
for(auto c:t)
{
s+="#";
s+=c;
}
s+="#^";
manacher(s);
int ans=0;
for(int i=0; i<s.size(); i++) ans=max(ans,d[i]-1);
cout<<ans;
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cout<<fixed<<setprecision(2);
int T=1;
while(T--)
{
O_o();
}
}
ACAM
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+77;
int id[N];
struct AC_automation
{
int tr[N][27],fail[N],ans[N],cnt=1,rd[N];
void insert(string s,int i)
{
int u=1;
for(auto c:s)
{
int v=c-'a';
if(!tr[u][v]) tr[u][v]=++cnt;
u=tr[u][v];
}
id[i]=u;
}
void build()
{
queue<int> q;
for(int i=0; i<26; i++) tr[0][i]=1;
q.push(1);
fail[1]=0;
while(!q.empty())
{
int u=q.front(); q.pop();
for(int i=0; i<26; i++)
{
if(tr[u][i])
{
fail[tr[u][i]]=tr[fail[u]][i];
rd[tr[fail[u]][i]]++;
q.push(tr[u][i]);
}
else tr[u][i]=tr[fail[u]][i];
}
}
}
void ask(string s)
{
int u=1;
for(auto t:s)
{
u=tr[u][t-'a'];
ans[u]++;
}
}
void query(string s)
{
ask(s);
queue<int> q;
for(int i=1; i<=cnt; i++) if(!rd[i]) q.push(i);
while(!q.empty())
{
int v=q.front(); q.pop();
int u=fail[v];
ans[u]+=ans[v];
rd[u]--;
if(!rd[u]) q.push(u);
}
}
}AC;
void O_o()
{
int n;
cin>>n;
for(int i=1; i<=n; i++)
{
string s;
cin>>s;
AC.insert(s,i);
}
AC.build();
string s;
cin>>s;
AC.query(s);
for(int i=1; i<=n; i++) cout<<AC.ans[id[i]]<<"\n";
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cout<<fixed<<setprecision(2);
int T=1;
while(T--)
{
O_o();
}
}
SAM(子串出现次数)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e6+77;
int cnt,dp[N],ls[N];
ll ans=0;
struct SAM
{
int fa,len,nxt[27];
}sam[N];
struct E
{
int to,next;
}e[N];
void add(int u,int v)
{
e[++cnt].to=v; e[cnt].next=ls[u]; ls[u]=cnt;
}
int last=1,tot=1;
void insert(int ch)
{
int cur=++tot,p;
sam[cur].len=sam[last].len+1;
dp[cur]=1;
for(p=last; (!sam[p].nxt[ch])&&p; p=sam[p].fa)
{
sam[p].nxt[ch]=cur;
}
int q=sam[p].nxt[ch];
if(!q)
{
sam[cur].fa=1;
}
else if(sam[q].len==sam[p].len+1)
{
sam[q].len=sam[p].len+1;
sam[cur].fa=q;
}
else if(sam[q].len!=sam[p].len+1)
{
int r=++tot;
sam[r]=sam[q];
sam[r].len=sam[p].len+1;
for(; sam[p].nxt[ch]==q; p=sam[p].fa)
sam[p].nxt[ch]=r;
sam[cur].fa=sam[q].fa=r;
}
last=cur;
}
void dfs(int u)
{
for(int i=ls[u]; i; i=e[i].next)
{
int v=e[i].to;
dfs(v);
dp[u]+=dp[v];
}
if(dp[u]!=1) ans=max(ans,1ll*dp[u]*sam[u].len);
}
void O_o()
{
string s;
cin>>s;
for(int i=0; i<s.size(); i++) insert(s[i]-'a');
for(int i=2; i<=tot; i++) if(sam[i].fa!=0)
{
add(sam[i].fa,i);
}
dfs(1);
cout<<ans;
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cout<<fixed<<setprecision(2);
int T=1;
while(T--)
{
O_o();
}
}
SAM封装版(LCP)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+77;
int a[N];
struct SAM
{
int tr[N][27],fa[N],len[N];
int tot=1,last=1;
void clone(int r,int q)
{
for(int i=0; i<26; i++) tr[r][i]=tr[q][i];
fa[r]=fa[q];
}
void insert(int ch)
{
int cur=++tot,p;
len[cur]=len[last]+1;
for(p=last; (!tr[p][ch])&&p; p=fa[p])
{
tr[p][ch]=cur;
}
int q=tr[p][ch];
if(!q)
{
fa[cur]=1;
}
else if(len[q]==len[p]+1)
{
fa[cur]=q;
}
else
{
int r=++tot;
clone(r,q);
len[r]=len[p]+1;
for(; tr[p][ch]==q; p=fa[p])
tr[p][ch]=r;
fa[cur]=fa[q]=r;
}
last=cur;
}
int query(string s)
{
int u=1,ass=0,ans=0;
for(auto c:s)
{
int v=c-'a';
if(tr[u][v])
{
ass++; u=tr[u][v];
}
else
{
for(; u&&(!tr[u][v]); u=fa[u]);
if(u)
{
ass=len[u]+1;
u=tr[u][v];
}
else
{
u=1;
ass=0;
}
}
ans=max(ans,ass);
}
return ans;
}
}SAM;
void O_o()
{
string s;
cin>>s;
for(auto c:s) SAM.insert(c-'a');
cin>>s;
cout<<SAM.query(s);
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cout<<fixed<<setprecision(2);
int T=1;
while(T--)
{
O_o();
}
}
SA
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+77;
int rk[N],sa[N],cnt[N],id[N],n,key[N],oldrk[N];
bool cmp(int x,int y,int w)
{
return (oldrk[x]==oldrk[y])&&(oldrk[x+w]==oldrk[y+w]);
}
void getSA(string s)
{
int m=127,p=0;
for(int i=1; i<=n; i++) cnt[rk[i]=s[i]]++;
for(int i=1; i<=m; i++) cnt[i]+=cnt[i-1];
for(int i=n; i>=1; i--) sa[cnt[rk[i]]--]=i;
for(int w=1; ; w<<=1,m=p)
{
p=0;
for(int i=n; i>n-w; i--) id[++p]=i;
for(int i=1; i<=n; i++)
if(sa[i]>w) id[++p]=sa[i]-w;
memset(cnt,0,sizeof(cnt));
for(int i=1; i<=n; i++) cnt[key[i]=rk[id[i]]]++;
for(int i=1; i<=m; i++) cnt[i]+=cnt[i-1];
for(int i=n; i>=1; i--) sa[cnt[key[i]]--]=id[i];
p=0;
for(int i=1; i<=n; i++) oldrk[i]=rk[i];
for(int i=1; i<=n; i++)
{
if(!cmp(sa[i],sa[i-1],w)) p++;
rk[sa[i]]=p;
}
if(p==n) break;
}
}
void getHeight()
{
int tot=0;
for(int i=1; i<=n; i++)
{
if(tot) tot--;
while(s[i+tot]==s[sa[rk[i]-1]+tot]) ++tot;
height[rk[i]]=tot;
}
}
void O_o()
{
string s;
cin>>s;
n=s.size();
s=' '+s;
getSA(s);
for(int i=1; i<=n; i++) cout<<sa[i]<<" ";
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cout<<fixed<<setprecision(2);
int T=1;
while(T--)
{
O_o();
}
}
PAM(子串出现次数)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+77,inf=2e9;
struct PAM
{
int siz,last,tot;
int cnt[N],ch[N][26],len[N],fail[N];
string s;
int add(int l)
{
siz++;
len[siz]=l;
fail[siz]=cnt[siz]=0;
return siz;
}
void init()
{
siz=-1;
last=tot=0;
s="$";
add(0);
add(-1);
fail[0]=1;
}
int getfail(int x)
{
while(s[tot-len[x]-1]!=s[tot])
x=fail[x];
return x;
}
void insert(char c)
{
s+=c;
tot++;
int now=getfail(last);
if(!ch[now][c-'a'])
{
int x=add(len[now]+2);
fail[x]=ch[getfail(fail[now])][c-'a'];
ch[now][c-'a']=x;
}
last=ch[now][c-'a'];
cnt[last]++;
}
}pam;
void solve()
{
int ans=0;
for(int i=pam.siz; i>=0; i--)
{
pam.cnt[pam.fail[i]]+=pam.cnt[i];
}
for(int i=1; i<=pam.siz; i++)
{
ans=max(ans,pam.cnt[i]*pam.len[i]);
}
cout<<ans;
}
void O_o()
{
string s;
cin>>s;
pam.init();
for(auto c:s)
{
pam.insert(c);
}
solve();
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cout<<fixed<<setprecision(2);
int T=1;
while(T--)
{
O_o();
}
}