没弄明白,做了几个题,也不懂,以后填坑
P3809 【模板】后缀排序
#include<bits/stdc++.h>
#define N 1000010
using namespace std;
int x[N],y[N],sa[N],h[N],rk[N],c[10*N],a[N];
char s[N];
int m,n;
void calcsa(int n,int m){
int p=0,f=0;
for(int i=1;i<=m;i++)c[i]=0;
for(int i=1;i<=n;i++)c[x[i]=a[i]]++;
for(int i=1;i<=m;i++)c[i]+=c[i-1];
for(int i=n;i;i--)sa[c[x[i]]--]=i;
for(int i=1;i<=n&&p<=n;i<<=1){
p=0;
for(int j=n-i+1;j<=n;j++)y[++p]=j;
for(int j=1;j<=n;j++)if(sa[j]>i)y[++p]=sa[j]-i;
for(int j=1;j<=m;j++)c[j]=0;
for(int j=1;j<=n;j++)c[x[y[j]]]++;
for(int j=1;j<=m;j++)c[j]+=c[j-1];
for(int j=n;j;j--)sa[c[x[y[j]]]--]=y[j];
swap(x,y);x[sa[1]]=1;p=2;
for(int j=2;j<=n;j++)
x[sa[j]]=y[sa[j]]==y[sa[j-1]]&&y[sa[j]+i]==y[sa[j-1]+i]?p-1:p++;
m=p;
}
}
int main(){
scanf("%s",s+1);int len=strlen(s+1);
for(int i=1;i<=len;i++)a[i]=s[i]-' ';
calcsa(len,10000);
for(int i=1;i<=len;i++)printf("%d ",sa[i]);
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1000010;
int n,last=1,cnt=1;
int a[maxn][26],mx[maxn],fa[maxn];
int T[maxn],Seq[maxn];
int f[maxn],w[maxn];
char s[maxn];
void insert(int c){
int p=last,np=last=++cnt;
mx[np]=mx[p]+1; f[np]=w[np]=1;
while(!a[p][c] && p) a[p][c]=np,p=fa[p];
if(!p) fa[np]=1;
else{
int q=a[p][c];
if(mx[q]==mx[p]+1) fa[np]=q;
else{
int nq=++cnt;mx[nq]=mx[p]+1;
memcpy(a[nq],a[q],sizeof(a[q]));
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
while(a[p][c]==q) a[p][c]=nq,p=fa[p];
}
}
}
ll solve(){ll ans=0;
for(int i=1;i<=cnt;i++) T[mx[i]]++;
for(int i=1;i<=n;i++) T[i]+=T[i-1];
for(int i=1;i<=cnt;i++) Seq[T[mx[i]]--]=i;
for(int i=cnt;i>=1;i--) f[fa[Seq[i]]]+=f[Seq[i]];
for(int i=cnt;i>=1;i--){int x=Seq[i];
ans+=(ll)f[x]*w[fa[x]]*mx[fa[x]];
w[fa[x]]+=f[x];
}
return ans;
}
int main(){
scanf("%s",s);n=strlen(s);
for(int i=n-1;i>=0;i--) insert(s[i]-'a');
ll ans=(ll)(1+n)*n*(n-1)/2;
ans-=solve()*2;
printf("%lld",ans);
return 0;
}
P1368 工艺
#include<cstdio>
#include<iostream>
#include<map>
#include<cstring>
using namespace std;
const int M=1012000;
int r[M],tmp[M],n,a[M];
struct SAM{
map<int,int>ch[M];int f[M],size[M],dis[M],cnt,last;
SAM(){cnt=last=1; }
void insert(int x){
int now=last,New=++cnt;last=cnt;size[New]=1;
dis[New]=dis[now]+1;
while(now&&!ch[now][x]) ch[now][x]=New,now=f[now];
if(!now) f[New]=1;
else{
int p=ch[now][x];
if(dis[p]==dis[now]+1) f[New]=p;
else{
int np=++cnt;ch[np]=ch[p];dis[np]=dis[now]+1;
f[np]=f[p];f[New]=f[p]=np;
while(now&&ch[now][x]==p) ch[now][x]=np,now=f[now];
}
}
}
void print(){int tmp=1;
for(int i=1;i<=n;i++){
printf("%d ",ch[tmp].begin()->first);
tmp=ch[tmp].begin()->second;
}
}
}T;
char s[M];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[n+i]=a[i];
for(int i=1;i<=n;i++) T.insert(a[i]);
for(int i=1;i<=n;i++) T.insert(a[i]);
T.print();
}
P3804 【模板】后缀自动机
// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
#include<map>
#include<cstring>
using namespace std;
const int M=2120000;
int len,r[M],tmp[M];
struct SAM{
int ch[M][30],f[M],size[M],dis[M],cnt,last;
SAM(){memset(ch,0,sizeof ch);memset(dis,0,sizeof dis);memset(f,0,sizeof f);memset(size,0,sizeof size);cnt=last=1; }
void insert(int x){
int now=last,New=++cnt;last=cnt;size[New]=1;
dis[New]=dis[now]+1;
while(now&&!ch[now][x]) ch[now][x]=New,now=f[now];
if(!now) f[New]=1;
else{
int p=ch[now][x];
if(dis[p]==dis[now]+1) f[New]=p;
else{
int np=++cnt;memcpy(ch[np],ch[p],sizeof(ch[p]));dis[np]=dis[now]+1;
f[np]=f[p];f[New]=f[p]=np;
while(now&&ch[now][x]==p) ch[now][x]=np,now=f[now];
}
}
}
long long query(){long long ans=0;
for(int i=1;i<=cnt;i++) r[dis[i]]++;
for(int i=1;i<=len;i++) r[i]+=r[i-1];
for(int i=1;i<=cnt;i++) tmp[r[dis[i]]--]=i;
for(int i=cnt;i;i--){
size[f[tmp[i]]]+=size[tmp[i]];
if(size[tmp[i]]>1)ans=max(ans,1ll*dis[tmp[i]]*size[tmp[i]]);
}
return ans;
}
void print(){printf("%lld ",query());}
}T;
char s[M];
int main(){
scanf("%s",s+1);
len=strlen(s+1);
for(int i=1;i<=len;i++) T.insert(s[i]-'a');
T.print();
}
P4070 [SDOI2016]生成魔咒
#include <iostream>
#include <cstdio>
#include <map>
#define ll long long
#define dist(x) (dis[x]-dis[fa[x]])
const int maxm=1e6+100;
std::map<int,int> ch[maxm*2];
int n,m,last=1,siz=1;
int fa[maxm],dis[maxm];
ll ans;
inline void insert(int x)
{
int now=last,son=last=++siz;
dis[son]=dis[now]+1;
while(now&&!ch[now][x]) ch[now][x]=son,now=fa[now];
if(!now) fa[son]=1,ans+=dist(son);
else { int q=ch[now][x];
if(dis[now]+1==dis[q]) fa[son]=q,ans+=dist(son);
else {
int nq=++siz;dis[nq]=dis[now]+1;ch[nq]=ch[q];
fa[nq]=fa[q];ans+=dist(nq)-dist(q);
fa[son]=fa[q]=nq;ans+=dist(son)+dist(q);
while(now&&ch[now][x]==q) ch[now][x]=nq,now=fa[now];
}
}
}
int main(){
int n;
scanf("%d",&n);
for(int i=1,x;i<=n;i++){
scanf("%d",&x);insert(x);
printf("%lld\n",ans);
}
return 0;
}