后缀自动机(不会点这里)
加入节点的时候记录一下这个点是不是代表后缀。建完以后重建一下后缀树在上面dfs就可以了= =(注意重建的时候是字典序排序,不是拓扑序
由于空间的关系,用map
#include<bits/stdc++.h> #define N 2000007 using namespace std; struct Node{ int fa,val,ri; map<int,int> c; }T[N]; int tot=1,last=1,np,nq,q,p[N],ans[N],tog,head[N],net[N],fall[N],len,c[67],id[N],Tot; char ch[N]; inline int gs(char c){ if ('0'<=c&&c<='9') return c-'0'; if ('A'<=c&&c<='Z') return c-'A'+10; if ('a'<=c&&c<='z') return c-'a'+36; } void write(int x) { if (x<10) {putchar('0'+x); return;} write(x/10),putchar('0'+x%10); } inline void writel(int x){ write(x),putchar(' '); } inline void Sam(int x,int y){ np=++tot; T[np].ri=T[np].val=T[last].val+1; for (;last&&!T[last].c[x];last=T[last].fa) T[last].c[x]=np; if (!last) T[np].fa=1; else { q=T[last].c[x]; if (T[last].val+1==T[q].val) T[np].fa=q; else { nq=++tot; T[nq]=T[q]; T[nq].val=T[last].val+1; T[q].fa=T[np].fa=nq; for(;last&&T[last].c[x]==q;last=T[last].fa) T[last].c[x]=nq; } } p[np]=y; last=np; } inline void add(int x,int y) { fall[++Tot]=y; net[Tot]=head[x]; head[x]=Tot; } void dfs(int x){ if (p[x]) ans[++tog]=p[x]; for (int i=head[x];i;i=net[i]) dfs(fall[i]); } int main() { // freopen("b.in","r",stdin); scanf("%s",ch); len=strlen(ch); for (int i=len-1;~i;i--) ch[i]=gs(ch[i]),Sam(ch[i],i+1); for (int i=tot;i;i--) c[ch[len-T[i].ri+T[T[i].fa].val]]++; for (int i=1;i<=64;i++) c[i]+=c[i-1]; for (int i=1;i<=tot;i++) id[c[ch[len-T[i].ri+T[T[i].fa].val]]--]=i; for (int i=tot;i;i--) add(T[id[i]].fa,id[i]); dfs(1); for (int i=1;i<=len;i++) writel(ans[i]); return 0; }