bzoj 2882: 工艺【SAM】
2024-09-07 18:32:51
看上去比较SA,但是在学SAM所以就用SAM来做……
把串复制一遍接在后面,对这个新串求SAM(这里的儿子节点要用map转移),然后从根节点每次都向最小的转移走,这样走n次转移的串就是答案
#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
const int N=1000005;
int n,a[N],fa[N],dis[N],la,cur=1,cnt=1;
map<int,int>ch[N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void ins(int c,int id)
{
la=cur,dis[cur=++cnt]=id;
int p=la;
for(;p&&!ch[p][c];p=fa[p])
ch[p][c]=cur;
if(!p)
fa[cur]=1;
else
{
int q=ch[p][c];
if(dis[q]==dis[p]+1)
fa[cur]=q;
else
{
int nq=++cnt;
dis[nq]=dis[p]+1;
// memcpy(ch[nq],ch[q],sizeof(ch[nq]));
for(map<int,int>::iterator it=ch[q].begin();it!=ch[q].end();it++)
ch[nq][it->first]=it->second;
fa[nq]=fa[q];
fa[q]=fa[cur]=nq;
for(;ch[p][c]==q;p=fa[p])
ch[p][c]=nq;
}
}
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
a[i]=a[i+n]=read();
for(int i=1;i<=2*n;i++)
ins(a[i],i);
for(int i=1,nw=1;i<=n;i++)
{
printf("%d ",ch[nw].begin()->first);
nw=ch[nw].begin()->second;
}
return 0;
}
最新文章
- 浅谈servlet
- PHP好任性 —— 大小写敏感有两种规则,然而并没有什么特别原因
- SpringMVC学习--校验
- css3渐变色彩
- Unable to create SVNRepository object
- 检测ADO.net拼接字符串中非法字符
- C# mvc--ORM框架中EF的作用和特点
- Tomcat 部署Undeployment Failure
- 性能测试 - some
- PE文件格式详解(下)
- linux--软件包管理工具
- UVa11054
- Bootstrap 栅格系统简单整理
- 装饰器模式 Decorator 结构型 设计模式 (十)
- strcpy_s和strcpy()
- ActiveMQ应用(1)-安装及示例
- Python网络编程,粘包、分包问题的解决
- CKEDITOR的内容js转码,C#控制器解码接收
- Java控制多线程执行顺序
- 20155330 2016-2017-2 《Java程序设计》第三周学习总结