poj 1509
求一个字符串在旋转置换群下最小字典表示。
用的是后缀数组(后缀自动机还是再听听jason_yu讲讲吧,关于right集合的部分还有问题)
最小表示法的思想很有好(判断两个对象在某一置换群划分下,是否等价,可以求出两个对象在该置换群划分下的最小表示,然后比较最小表示)
#include <cstdio>
#include <cstring>
#define min(a,b) ((a)<(b)?(a):(b))
#define N 20010 int n, aa[N];
int sa[N], rk[N], ht[N], vv[N]; void expand( int *s, int *r, int *sa, int *rk, int k ) {
for( int i=; i<=n; i++ )
vv[r[s[i]]]=i;
for( int i=n; i>=; i-- )
if( s[i]>k ) sa[vv[r[s[i]-k]]--] = s[i]-k;
for( int i=n-k+; i<=n; i++ )
sa[vv[r[i]]--] = i;
for( int i=; i<=n; i++ )
rk[sa[i]] = rk[sa[i-]]+(r[sa[i]]!=r[sa[i-]]||r[sa[i]+k]!=r[sa[i-]+k]);
}
void calcht() {
for( int i=,k=; i<=n; i++ ) {
if( rk[i]== ) {
k = ht[i] = ;
continue;
}
int j=sa[rk[i]-];
while( aa[i+k]==aa[j+k] ) k++;
ht[i] = k;
if( k> ) k--;
}
}
void suffix() {
static int tsa[N], trk[N];
for( int i=; i<=; i++ ) vv[i] = ;
for( int i=; i<=n; i++ ) vv[aa[i]]++;
for( int i=; i<=; i++ ) vv[i]+=vv[i-];
for( int i=n; i>=; i-- ) sa[vv[aa[i]]--]=i;
for( int i=; i<=n; i++ )
rk[sa[i]] = rk[sa[i-]]+(aa[sa[i]]!=aa[sa[i-]]);
for( int k=; k<n; k<<= ) {
expand( sa, rk, tsa, trk, k );
for( int i=; i<=n; i++ )
sa[i]=tsa[i], rk[i]=trk[i];
}
calcht();
}
int sov() {
int nn = (n+)>>;
for( int i=; i<=n; i++ )
if( n-sa[i]+>=nn ) {
int rt = sa[i];
for( int j=i+; j<=n && ht[sa[j]]>=nn; j++ )
rt = min( rt, sa[j] );
return rt;
}
return -;
}
int main() {
int T;
scanf( "%d", &T );
while( T-- ) {
static char buf[N];
scanf( "%s", buf+ );
n = strlen( buf+ );
for( int i=; i<=n; i++ )
aa[i+n] = aa[i] = buf[i]-'a'+;
n += n;
suffix();
printf( "%d\n", sov() );
}
}
poj 1509的更多相关文章
- POJ 1509 最小表示法
题目链接:http://poj.org/problem?id=1509 题意:给定一个字符串,求一个起点使字符串从该起点起的字符串字典序最小[题目的字符串起点从1开始] 思路:最小表示法模板题 #de ...
- ●POJ 1509 Glass Beads
题链: http://poj.org/problem?id=1509 题解: 给出一个字符串,有一个操作:把首字符放到末尾,形成新的串.求任意次操作后,字典序最小的串的首字母在原串中的位置.(这就是最 ...
- POJ 1509 Glass Beads 后缀自动机 模板 字符串的最小表示
http://poj.org/problem?id=1509 后缀自动机其实就是一个压缩储存空间时间(对节点重复利用)的储存所有一个字符串所有子串的trie树,如果想不起来长什么样子可以百度一下找个图 ...
- POJ 1509 Glass Beads【字符串最小表示法】
题目链接: http://poj.org/problem?id=1509 题意: 求循环字符串的最小表示. 分析: 浅析"最小表示法"思想在字符串循环同构问题中的应用 判断两字符串 ...
- POJ 1509 Glass Beads
Description 求字符串的最小循环表示. Sol SAM. 把原串复制一遍,建出SAM,然后每次选最小的一个跑 \(len\) 次,这就是最小循环表示的最后一个节点,然后 \(x-len+1\ ...
- UVA 719 / POJ 1509 Glass Beads (最小表示法/后缀自动机)
题目大意: 给出一个长度为N的字符串,求其字典序最小的循环同构. N<=10W. 算法讨论: 算法一.最小表示法.定义题. 算法二.后缀自动机. Codes: #include <iost ...
- POJ 1509 Glass Beads---最小表示法
题意: T组数据,每组数据给出一个字符串,求这个字符串的最小表示发(只要求输出起始位置坐标) SAM入门题(检测板子是否正确). 将字符串S加倍丢进SAM中,然后走字符串长度次,每次贪心的沿最小的边走 ...
- POJ 1509 循环同构的最小表示法
题目大意: 给定一个字符串,可以把一段尾部接到头部,这样找到一个最小的字符串 方案一: 利用循环同构中找最小表示的方法来解决 论文参考http://wenku.baidu.com/view/438ca ...
- CSU训练分类
√√第一部分 基础算法(#10023 除外) 第 1 章 贪心算法 √√#10000 「一本通 1.1 例 1」活动安排 √√#10001 「一本通 1.1 例 2」种树 √√#10002 「一本通 ...
随机推荐
- go 流程控制
if else 语句 基本语法 if condition { //do something } if condition { //do something } else if condition { ...
- numpy细碎知识点
np.random.rand() 基于python自带模块random的random函数的一个延伸吧,生成指定数量的列表 np.random.rand(a,b) 参数a,b均为整型,生成含有a个元素的 ...
- python实现单单链表
# -*- coding: utf-8 -*- # @Time : 2018/9/28 22:09 # @Author : cxa # @File : node.py # @Software: PyC ...
- 前端打包工具之fis3的初级使用
说到打包工具,大家都会想到webpack,我之前也接触过webpack,说实话个人觉得webpack上手容易,但是对于新手来说里面有太多坑,配置文件也不简单.于是乎,我转入了fis3阵营,发现fis3 ...
- jmert jdbc request支持执行多条sql语句并设置jdbc字符集
1.jdbc request支持执行多条sql语句 在JDBC Connection Configuration中的sql连接字串中添加如下内容 allowMultiQueries=true 如下图: ...
- group by 和 distinct 去重比较
distinct方式就是两两对比,需要遍历整个表.group by分组类似先建立索引再查索引,所以两者对比,小表destinct快,不用建索引.大表group by快.一般来说小表就算建索引,也不会慢 ...
- Flask 对象关系
建立一个关系 from sqlalchemy import Column, Integer, String, MetaData, ForeignKey from sqlalchemy.ext.decl ...
- CVE-2012-1876Microsoft Internet Explorer Col元素远程代码执行漏洞分析
Microsoft Internet Explorer是微软Windows操作系统中默认捆绑的WEB浏览器. Microsoft Internet Explorer 6至9版本中存在漏 ...
- GUC-6 Callable 接口
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.ut ...
- LoadRunner对不同协议的选择
LoadRunner对不同协议的选择 大家常用的是Loadrunner测试web(Http/Html),但其实协议多种多样.在B/S结构的网站多种业务的特点需要选择不同的协议,协议如何选择呢,寻找了相 ...