BZOJ 2882 工艺 (字符串最小循环同构)
题目大意:
给一个长度小于等于30W的数列,求其最小循环同构。
算法讨论:
在自动机长倍长走S后即可。注意这里面是数字,要用map存储。 今天才知道要开四倍长。
Codes:
#include <bits/stdc++.h>
using namespace std; const int L = + ; int n, a[L<<], ans; struct State{
int len, pre;
map <int, int> next; State(){
len = pre = ;
next.clear();
}
void clear(){
len = pre = ;
next.clear();
}
}st[L<<]; struct SuffixAutomaton{
int sz, last; void Init(){
last = sz = ;
st[].len = ; st[].pre = -;
sz ++;
}
void Extend(int c){
int cur = sz ++;
st[cur].len = st[last].len + ;
int p; for(p = last; p != - && !st[p].next[c]; p = st[p].pre)
st[p].next[c] = cur; if(p == -) st[cur].pre = ;
else{
int q = st[p].next[c];
if(st[q].len == st[p].len + ) st[cur].pre = q;
else{
int cle = sz ++;
st[cle].len = st[p].len + ;
st[cle].pre = st[q].pre;
st[cle].next = st[q].next;
for(; p != - && st[p].next[c] == q; p = st[p].pre)
st[p].next[c] = cle;
st[q].pre = st[cur].pre = cle;
}
}
last = cur;
}
}SAM; void Input(){
scanf("%d", &n);
for(int i = ; i < n; ++ i)
scanf("%d", &a[i]);
}
void Output(){
bool flag = false;
for(int i = ans; i < ans + n; ++ i){
if(!flag){
flag = true;
printf("%d", a[i % n]);
}
else
printf(" %d", a[i % n]);
} printf("\n");
} void Solve(){
SAM.Init();
for(int i = ; i < n; ++ i)
a[i + n] = a[i];
for(int i = ; i < (n<<); ++ i)
SAM.Extend(a[i]); int p = ;
map <int, int>:: iterator pos; for(int i = ; i < n; ++ i){
for(pos = st[p].next.begin(); pos != st[p].next.end(); ++ pos){
p = (*pos).second;
break;
}
} ans = st[p].len - n;
} int main(){ Input();
Solve();
Output(); return ;
}
BZOJ 2882
BZOJ 2882 工艺 (字符串最小循环同构)的更多相关文章
- hdu 4333"Revolving Digits"(KMP求字符串最小循环节+拓展KMP)
传送门 题意: 此题意很好理解,便不在此赘述: 题解: 解题思路:KMP求字符串最小循环节+拓展KMP ①首先,根据KMP求字符串最小循环节的算法求出字符串s的最小循环节的长度,记为 k: ②根据拓展 ...
- BZOJ 2882: 工艺
2882: 工艺 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 599 Solved: 268[Submit][Status][Discuss] D ...
- BZOJ 2882: 工艺( 后缀自动机 )
把串S复制成SS然后扔进后缀自动机里, 从根选最小的儿子走, 走N步就是答案了...一开始还想写个treap的...后来觉得太麻烦..就用map了... ----------------------- ...
- poj 2406 Power Strings【字符串+最小循环节的个数】
Po ...
- KMP解决字符串最小循环节相关问题
经典问题 : 给出一个由某个循环节构成的字符串,要你找出最小的循环节,例如 abababab 最小循环节当是 ab ,而类似 abab 也可以成为它的循环节,但并非最短. 分析 : 对于上述问题有两个 ...
- BZOJ.2882.工艺(后缀自动机 最小表示 map)
题目链接 BZOJ 洛谷 SAM求字符串的最小循环表示. 因为从根节点出发可以得到所有子串,所以每次找字典序最小的一个出边走即可.因为长度问题把原串再拼接在后面一次. 需要用map存转移.复杂度O(n ...
- BZOJ 2882 工艺 ——后缀自动机 最小表示法
先说后缀自动机的做法. 直接把S串复制一遍成SS,然后建立后缀自动机,go边相当于在当前字符的后面插入,而son边可以看作在字符串前面加一个字符. 所以贪心的走字典序最小的边即可,而且根据后缀自动机的 ...
- BZOJ 2882: 工艺 (SA/SAM/最小表示法)
我写的O(nlogn)O(nlogn)O(nlogn)的SA 8000ms 被 O(n)O(n)O(n)的SAM 2800ms 和 O(n)O(n)O(n)的最小表示法 500ms 头都锤爆- COD ...
- 【刷题】BZOJ 2882 工艺
Description 小敏和小燕是一对好朋友. 他们正在玩一种神奇的游戏,叫Minecraft. 他们现在要做一个由方块构成的长条工艺品.但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工 ...
随机推荐
- birt报表图标中文显示为框框的解决方法
birt报表中图标部分的中文显示为框框,其他部分中文显示正常 解决办法:修改jdk中的字体设置/jdk1.6.0_13/jre/lib /fonts/fonts.dir 1.将宋体字体copy到/jd ...
- Effective Java 电子书 apk版本下载
下载安装包以后,安装即可阅读该书了,并且实时展示每章节代码哦,并且可以运行哦,赶快下载体验吧. Effective Java中文第二版下载地址:下载 应用截图:
- linux系统结构和系统命令初步
以上是第五课和第14课笔记 linux 基本结构: 系统构成:kernel,Modules,Lib,(Shell,Tool)系统引导:BIOS -> Bootlooder -> Kerne ...
- Oracle 10g RAC启动与关闭命令
一. 检查共享设备 一般情况下, 存放OCR 和 Voting Disk 的OCFS2 或者raw 都是自动启动的. 如果他们没有启动,RAC 肯定是启动不了的. 1.1 如果使用ocfs2的,检查o ...
- curl 网页抓取
如果要把这个网页保存下来,可以使用-o参数,这就相当于使用wget命令了. curl -o [文件名] www.tvbs.cc 二.自动跳转 有的网址是自动跳转的.使用-L参数,curl就会跳转到新的 ...
- .net 分页案例效果
; ) { pageUrl += ) + && (totalPageCount > step ...
- 使用itextsharp创建PDF文档——图片集合
文档管理系统中 ,扫描模块将文档或证件扫描后.为了便于保存多个图片,拟将多个图片生成一个PDF文档进行保存. 这里我们就需要PDF生成工具了.你可以在这里下载.PDFCreator 主要使用了开源工具 ...
- QT 4.7支持中文(QT4.7)(中文)(makeqpf)
QT 4.7支持中文(QT4.7)(中文)(makeqpf) 摘要: QT4.7.0在移植到开发板上的时候,中文支持是必不可少的,如何让QT支持中文,如何制作QT支持的字体文件,如何使QT UI编辑器 ...
- hdu 3635 Dragon Balls(并查集应用)
Problem Description Five hundred years later, the number of dragon balls will increase unexpectedly, ...
- hdu 5344 MZL's xor(数学之异或)
Problem Description MZL loves xor very much.Now he gets an array A.The length of A ≤i,j≤n) The xor ...