题目描述:
雾.
题目分析:
裸的最小循环同构.
我们只需要用SAM把串插入两次.
输出每次输出最小的边,然后去往下一个点
题目链接:
题外话
std::pair
Ac 代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <map>
const int maxm=2*600000;
struct node{
int fa,len;
std::map<int,int> son;
}t[maxm];
int last=1,siz=1,root=1,n;
int s[maxm];
inline void extend(int c)
{
int p=last,np=++siz;
last=np;
t[np].len=t[p].len+1;
while(p&&!t[p].son[c]) t[p].son[c]=np,p=t[p].fa;
if(!p) t[np].fa=1;
else
{
int q=t[p].son[c];
if(t[p].len+1==t[q].len) t[np].fa=q;
else
{
int nq=++siz;
t[nq]=t[q];
t[nq].len=t[p].len+1;
t[q].fa=t[np].fa=nq;
while(p&&t[p].son[c]==q) t[p].son[c]=nq,p=t[p].fa;
}
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&s[i]),extend(s[i]);
for(int i=1;i<=n;i++) extend(s[i]);
int p=1;
for(int i=1;i<=n;i++)
{
printf("%d ",t[p].son.begin()->first);
p=t[p].son.begin()->second;
}
return 0;
}