个人使用的一些模板
Posted OIerC
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了个人使用的一些模板相关的知识,希望对你有一定的参考价值。
个人码风:大括号换行,4格缩进,轻微压行,行内空格极随意。
字符串
KMP
const int N=1000005;
char s[N], t[N];
int len_s, len_t, nxt[N];
void GetNext(char *s)
{
for (int i=2, k=0; i<=len_s; i++)
{
while (k && s[i]!=s[k+1]) k=nxt[k];
if (s[i]==s[k+1]) k++; nxt[i]=k;
}
}
void KMP(char *s, char *t)
{
for (int i=1, k=0; i<=len_t; i++)
{
while (k && t[i]!=s[k+1]) k=nxt[k];
if (t[i]==s[k+1]) k++;
if (k==len_s){printf("%d\n", i-len_s+1); k=nxt[k];}
}
}
SAM
inline void chkmax(int &x, int y){x<y?(x=y):0;}
inline void chkmin(int &x, int y){x>y?(x=y):0;}
const int N=1000005;
int son[N<<1][26], fa[N], len[N], last, cnt;//insert
int a[N], t[N], size[N];//sort
int mn[N], mx[N];//Get_N_LCS
int sum[N];//Get_Kth_Substr
char s[N];
namespace SuffixAutoMaton
{
inline int read()
{
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
void insert(int c)
{
int p=last, np=last=++cnt; len[np]=len[p]+1;
for (; p&&!son[p][c]; p=fa[p]) son[p][c]=np;
if (!p) fa[np]=1;
else
{
int q=son[p][c];
if (len[p]+1==len[q]) fa[np]=q;
else
{
int nq=++cnt; len[nq]=len[p]+1;
memcpy(son[nq], son[q], sizeof(son[q]));
fa[nq]=fa[q]; fa[q]=fa[np]=nq;
for (; son[p][c]==q; p=fa[p]) son[p][c]=nq;
}
}
size[np]=1;
}
void Sort()
{
for (int i=1; i<=cnt; i++) t[len[i]]++;
for (int i=1; i<=cnt; i++) t[i]+=t[i-1];
for (int i=1; i<=cnt; i++) a[t[len[i]]--]=i;
for (int i=cnt; i; i--) size[fa[a[i]]]+=size[a[i]];
}
void build()
{
scanf("%s", s+1); last=cnt=1; int len=strlen(s+1);
for (int i=1; i<=len; i++) insert(s[i]-'a');
}
void Get_LCS()
{
build(); scanf("%s", s+1);
int n=strlen(s+1), p=1, Len=0, ans=0;
for (int i=1; i<=n; i++)
{
int c=s[i]-'a';
if (son[p][c]) p=son[p][c], Len++;
else
{
for (; p&&!son[p][c]; p=fa[p]);
if (p) Len=len[p]+1, p=son[p][c];
else p=1, Len=0;
}
ans=max(ans, Len);
}
printf("%d\n", ans);
}
void Get_N_LCS()
{
memset(mn, 0x3f, sizeof(mn));
build(); Sort(); int ans=0;
while (~scanf("%s", s+1))
{
int n=strlen(s+1), p=1, Len=0;
for (int i=1; i<=n; i++)
{
int c=s[i]-'a';
if (son[p][c]) Len++, p=son[p][c], chkmax(mx[p], Len);
else
{
for (; p&&!son[p][c]; p=fa[p]);
if (p) Len=len[p]+1, p=son[p][c], chkmax(mx[p], Len);
else Len=0, p=1;
}
}
for (int i=cnt; i; i--)
{
int u=a[i];
chkmax(mx[fa[u]], min(mx[u], len[fa[u]]));
chkmin(mn[u], mx[u]); mx[u]=0;
}
}
for (int i=1; i<=cnt; i++) chkmax(ans, mn[i]);
printf("%d\n", ans);
}
void Get_Kth_Dif_Substr()
{
Sort();
for (int i=1; i<=cnt; i++) sum[i]=size[i]=1; sum[1]=size[1]=0;
for (int i=cnt; i; i--)
for (int j=0; j<26; j++) sum[a[i]]+=sum[son[a[i]][j]];
int k=read(), u=1;
if (sum[1]<k) {puts("-1"); exit(0);}
while (k>0)
{
for (int i=0; i<26; i++) if (son[u][i])
{
if (sum[son[u][i]]<k) k-=sum[son[u][i]];
else{putchar(i+'a'); u=son[u][i]; k--; break;}
}
}
puts("");
}
void Get_Kth_Substr()
{
Sort();
for (int i=1; i<=cnt; i++) sum[i]=size[i]; sum[1]=size[1]=0;
for (int i=cnt; i; i--)
for (int j=0; j<26; j++) sum[a[i]]+=sum[son[a[i]][j]];
int k=read(), u=1; if (sum[1]<k) {puts("-1"); exit(0);}
while (k>0)
{
for (int i=0; i<26; i++) if (son[u][i])
{
if (sum[son[u][i]]<k) k-=sum[son[u][i]];
else{putchar(i+'a'); u=son[u][i]; k-=size[u]; break;}
}
}
puts("");
}
}
SA
[待填坑]
AC自动机(Trie图)
const int N=1000005;
struct node{int fail, num, son[26];}t[N];
int cnt; char s[N];
namespace Aho_Corasick_Automaton
{
inline int read()
{
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
void insert(char *s)
{
int len=strlen(s+1), p=0;
for (int i=1; i<=len; i++)
{
int c=s[i]-'a';
if (!t[p].son[c]) t[p].son[c]=++cnt;
p=t[p].son[c];
}
t[p].num++;
}
void build_AC()
{
queue<int> q;
for (int i=0; i<26; i++) if (t[0].son[i]) q.push(t[0].son[i]);
while (!q.empty())
{
int now=q.front(), fail=t[now].fail; q.pop();
for (int i=0; i<26; i++)
{
int son=t[now].son[i];
if(son) t[son].fail=t[fail].son[i], q.push(son);
else t[now].son[i]=t[fail].son[i];
}
}
}
int find(char *s)
{
int len=strlen(s+1), pos=0, res=0;
for (int i=1; i<=len; i++)
{
int c=s[i]-'a', now=pos=t[pos].son[c];
while (now && t[now].num!=-1)
{
res+=t[now].num; t[now].num=-1;
now=t[now].fail;
}
}
return res;
}
void Build()
{
for (int i=1, n=read(); i<=n; i++)
scanf("%s", s+1), insert(s);
build_AC();
}
}
Manacher
const int N=11000005;
char t[N], s[N<<1]; int p[N<<1];
int main()
{
scanf("%s", t+1); int n=strlen(t+1), ans=0;
for (int i=1; i<=n; i++) s[i<<1]=t[i], s[i<<1|1]='#';
(n<<=1)+=2; s[1]=s[n]='#';
for (int i=1, maxr=0, mid=0; i<=n; i++)
{
p[i]=(i<maxr)?min(p[2*mid-i], p[mid]+mid-i):1;
while (i+p[i]<=n && s[i+p[i]]==s[i-p[i]]) p[i]++;
if (p[i]+i>maxr) maxr=p[i]+i, mid=i;
}
for (int i=1; i<=n; i++) ans=max(ans, p[i]-1);
printf("%d\n", ans);
return 0;
}
最小表示法
int main()
{
int n=read(), k=0, i=0, j=1;
for (int i=0; i<n; i++) a[i]=read();
while (k<n && i<n && j<n)
{
if (a[(i+k)%n]==a[(j+k)%n]) k++;
else
{
a[(i+k)%n]>a[(j+k)%n]?i=i+k+1:j=j+k+1;
i==j?i++:0; k=0;
}
} j=min(i, j);
for (int i=j; i<n; i++) printf("%d ", a[i]);
for (int i=0; i<j; i++) printf("%d ", a[i]);
}
以上是关于个人使用的一些模板的主要内容,如果未能解决你的问题,请参考以下文章