目录

  • @description@
  • @solution@
  • @accepted code@
  • @details@


@description@

给定一个由小写字母构成的圆环形的字符串(即首字母和末字母是相连的)。
让你找到一个位置将这个圆环形的串断开成为一个序列形的串,使得这个字符串字典序最小。如果有多个,输出位置最靠前的那一个。

input
多组数据。第一行输入数据组数 N。
接下来 N 行,每行一个长度不超过 10000 个字符的字符串。保证仅由小写字母组成。

output
对于每组数据,输出一个位置。表示以这个位子作为字符串起点字符串的字典序最小。

sample input
4
helloworld
amandamanda
dontcallmebfu
aaabaaa
sample output
10
11
6
5

@solution@

据说这道题可以用什么……最小表示法来做。不过我觉得反正后缀自动机也不难写,就直接用后缀自动机吧。

圆环嘛,我们就把原字符串 S 后面再拼一个 S ,然后求 SS 长度为 |S| 且字典序最小的串嘛。
后缀自动机中每一个结点都可以表示若干子串。
那我从起始结点出发,每次总是沿着字典序最小的边走,走 |S| 步不就可以了嘛。

它还要求位置最靠前。后缀自动机里面跟位置有关的,就是 end-pos 嘛。那我就是 end-pos 集合里面最小的那个再减去字符串长度就可以了嘛。

跟求解子串出现次数一样,我们把每次通过增量法增加的结点视为有效结点,再通过桶排序向 fa 转移,转移时取最小值即可。

@accepted code@

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF = (1<<30);
const int MAXN = 10000;
struct sam{sam *fa, *ch[26]; int mx;sam *nxt; int mnps;
}pl[4*MAXN + 5], *bin[2*MAXN + 5], *tcnt, *root, *lst;
void init() {tcnt = root = lst = &pl[0];for(int i=0;i<26;i++)root->ch[i] = NULL;root->nxt = root->fa = NULL;root->mx = 0, root->mnps = INF;
}
sam *newnode(int x = INF) {tcnt++;for(int i=0;i<26;i++)tcnt->ch[i] = NULL;tcnt->nxt = tcnt->fa = NULL;tcnt->mx = 0, tcnt->mnps = x;return tcnt;
}
void add_bin(sam *x) {x->nxt = bin[x->mx];bin[x->mx] = x;
}
char s[MAXN + 5];
void clone(sam *x, sam *y) {for(int i=0;i<26;i++)x->ch[i] = y->ch[i];x->fa = y->fa;
}
void sam_extend(int pos, int x) {sam *cur = newnode(pos), *p = lst;cur->mx = lst->mx + 1; lst = cur;add_bin(cur);while( p && !p->ch[x] )p->ch[x] = cur, p = p->fa;if( !p )cur->fa = root;else {sam *q = p->ch[x];if( p->mx + 1 == q->mx )cur->fa = q;else {sam *nq = newnode();clone(nq, q);nq->mx = p->mx + 1;add_bin(nq);cur->fa = q->fa = nq;while( p && p->ch[x] == q )p->ch[x] = nq, p = p->fa;}}
}
void solve() {init(); scanf("%s", s);int lens = strlen(s);for(int i=0;i<lens;i++)sam_extend(i, s[i]-'a');for(int i=0;i<lens;i++)sam_extend(lens+i, s[i]-'a');for(int i=2*lens;i>=1;i--)while( bin[i] ) {bin[i]->fa->mnps = min(bin[i]->fa->mnps, bin[i]->mnps);bin[i] = bin[i]->nxt;}sam *nw = root;for(int i=0;i<lens;i++) {for(int j=0;j<26;j++)if( nw->ch[j] ) {nw = nw->ch[j];break;}}printf("%d\n", (nw->mnps + 1)%lens + 1);
}
int main() {int N; scanf("%d", &N);for(int i=1;i<=N;i++) solve();
}

@details@

注意因为字符串扩展成了两倍,所以数组要相应的开成两倍大。否则会 RE。

转载于:https://www.cnblogs.com/Tiw-Air-OAO/p/10252268.html

@poj - 1509@ Glass Beads相关推荐

  1. POJ 1509 Glass Beads 后缀自动机

    求给定字符串s从哪个位置开始的循环同构串字典序最小. 如果复制一遍s,发现其所有循环同构都是新字符串ss的长度为|s|的子串. 于是后缀自动机..dfs,不断地走字典序最小的边,直到走了|s|次即可. ...

  2. POJ - 1509 Glass Beads

    传送门 最小表示法模板 //Achen #include<algorithm> #include<iostream> #include<cstring> #incl ...

  3. POJ 1509 Glass Beads

    Description 求字符串的最小循环表示. Sol SAM. 把原串复制一遍,建出SAM,然后每次选最小的一个跑 \(len\) 次,这就是最小循环表示的最后一个节点,然后 \(x-len+1\ ...

  4. UVA719 Glass Beads 最小表示 / 后缀自动机

    传送门 题意: 求sss的最小表示. ∣s∣≤1e4|s|\le 1e4∣s∣≤1e4 思路: 可以选择直接套最小表示法的板子,但也可以将sss复制,即ss=s+sss=s+sss=s+s,对ssss ...

  5. 【POJ1509】Glass Beads 【后缀自动机】

    题意 给出一个字符串,求它的最小表示法. 分析 这个题当然可以用最小表示法做啦!但是我是为了学后缀自动机鸭! 我们把这个字符串长度乘二,然后建SAM,然后在SAM上每次跑最小的那个字母,找出长度为n的 ...

  6. (Incomplete) UVa 719 Glass Beads

    方法:最小表示法 题意及求一个string最小表示法的启示index.套用模版即可. code: 1 #include <cstdio> 2 #include <cstring> ...

  7. POJ1509 Glass Beads [后缀自动机]

    题意: 给一个字符串S,每次可以将它的第一个字符移到最后面,求这样能得到的字典序最小的字符串.输出开始下标 练习SAM第一题! SS构造SAM,然后从开始尽量走最小走n步就可以啦 什么?开始位置?!R ...

  8. Glass Beads

    是一个裸的最小表示法问题 #include<iostream> using namespace std; int t,n; string str; int getmin() {int i= ...

  9. 《挑战程序设计竞赛(第2版)》习题册攻略

    本项目来源于GitHub 链接: 项目GitHub链接 1 前言 项目为<挑战程序设计竞赛(第2版)>习题册攻略,已完结.可配合书籍或笔记,系统学习算法. 题量:约200道,代码注释内含详 ...

最新文章

  1. 一文读懂比特币现金(BCH)
  2. virtualbox主机网络管理 未能创建_NETworkManager(网络管理软件)官方版2020.12.0下载
  3. Linux学习之系统编程篇:程序、进程、并发、并行
  4. iOS标准库中常用数据结构和算法之二叉排序树
  5. 51单片机外部地址c语言,cx51与c语言对单片机内部和外部资源变量和地址的定义是否兼容?为什么...
  6. Kali Linux安装Remmina无法加载RDP插件
  7. matlab图像融合代码,图像融合+源代码+matlab
  8. 过滤内网IP—IPv4
  9. 归并排序(包含逆序数对的个数51Nod1019)
  10. CSS 3之美化表格样式
  11. ssh 登录linux xsell 登录Linux 提示用户密钥登录怎么解决
  12. HTML姓名转为拼音,EXCEL如何自动将姓名转换为拼音?
  13. 字符个数统计 java
  14. web前端期末大作业—— HTML+CSS豪华车 (9页)
  15. subDomainsBrute 子域名工具 源码分析
  16. 技术创业者必读:从验证想法到技术产品商业化的全方位解析
  17. CADD课程学习(10)-- 模拟不同体系与蛋白-蛋白相互作用(ZDOCK)
  18. 【人工智能】拥抱人工智能,从机器学习开始
  19. 纪念杰克韦尔奇:职业经理人怎么做变革
  20. 技嘉服务器主板装系统,技嘉AB350M-DS3H主板u盘重装系统win7教程

热门文章

  1. WKWebView高度自适应三种方式
  2. MySQL 目录结构信息
  3. Oracle 分区表的新增、修改、删除、合并。普通表转分区表方法
  4. ubuntu 中安装memcache,并给出一个简单的实例·
  5. Saltstack系列之一——安装篇
  6. 计算机专业申请,申请计算机专业
  7. FPGA详细芯片结构
  8. Matlab生成Xilinx Rom IP CORE的初始化内容coe文件
  9. C++实现在正方体8个顶点上放数字使得三组相对的面上的4个顶点的和都相等
  10. python导入自定义模块和路径问题