Minimum Index

题意

求字符串所有前缀的所有后缀表示中字典序最小的位置集合,最终转换为1112进制表示。比如aab,有三个前缀分别为a,aa,aab。其中a的后缀只有一个a,位置下标1;aa有两个后缀,字典序最小的是a,下标为2;aab有三个后缀,字典序最小的是aab,下标是1。答案为 \(1*(1112)^2+2*(1112)^1+1*(1112)^0\)

字符串长度1e6

分析

在求字符串的最小表示法中,有一个叫做Lyndon分解的求法,Lyndon分解可以使用Duval算法。详情可以参考 oi-wiki

设\(d[j]\) 为前缀 j 的字典序最小后缀的起始位置,i, j, k 指针与oi-wiki中介绍的一致。对于下面三种情况讨论d[j]的求解

\(j - k\) 为 近似Lyndon串前缀的循环节长度。

  1. \(s[j] == s[k]\), 那么d[j] = d[k] + (j - k); 本质上是取了 j 所在循环节的开头位置。(\(s=www\overline{w}\) 中 \(\overline{w}\) 的开头)
  2. \(s[j] > s[k]\),那么 d[j] = i; 当前\(s[i..j]\) 是一个Lyndon串,所以d[j] = i;
  3. \(s[j] < s[k]\),Duval算法中会重新处理 j 所在的这一段(\(s=www\overline{w}\) 中 \(\overline{w}\)), i会被置为这一段的开头,继续后面的分解过程。这里有一个特殊情况需要考虑,如果 \(j == k + 1\),那么 j 就是下一次分解的开头, i 会被置为 j,所以要手动将d[j] = j。
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
#define dbg(x...) do { cout << "\033[32;1m" << #x <<" -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<class T, class... Ts> void err(const T& arg,const Ts&... args) { cout << arg << " "; err(args...); }
const int N = 1e6 + 5;
const int mod = 1e9 + 7;
char s[N];
ll d[N], n; int main(){
int T;scanf("%d", &T);
while(T--){
scanf("%s", s + 1);
n = strlen(s + 1);
int i = 1; d[1] = 1;
while(i <= n) {
int j = i + 1, k = i;
while(j <= n && s[k] <= s[j]) {
if(s[k] == s[j]){
d[j] = d[k] + (j - k);
k ++;
}
else {
d[j] = i;
k = i;
}
j ++;
}
d[j] = j; // 当 k == j - 1 时,必须有这一条。因为下面的循环结束后,i = k + 1 也就是 j,接下来的大循环不会在处理当前的 j, 这次 j 是被当做lyndon分解串的一个起点对待的。
while(i <= k) i += j - k;
}
ll res = 0;
for(int i = n;i>=1; i --){
res = res * 1112 + d[i];
res %= mod;
}
printf("%lld\n", res);
}
return 0;
}

HDU - 6761 Minimum Index (字符串,Lyndon分解)的更多相关文章

  1. LOJ129 Lyndon 分解

    Lyndon 分解 样例 样例输入 1 ababa 样例输出 1 2 4 5 样例输入 2 bbababaabaaabaaaab 样例输出 2 1 2 4 6 9 13 18 样例输入 3 azAZ0 ...

  2. 【Leetcode_easy】599. Minimum Index Sum of Two Lists

    problem 599. Minimum Index Sum of Two Lists 题意:给出两个字符串数组,找到坐标位置之和最小的相同的字符串. 计算两个的坐标之和,如果与最小坐标和sum相同, ...

  3. 知识点简单总结——Lyndon分解

    知识点简单总结--Lyndon分解 Lyndon串 定义:一个字符串的最小后缀就是整个串本身. 等效理解:这个串为其所有循环表示中最小的. Lyndon分解 定义:将字符串分割为 $ s_{1} s_ ...

  4. hdu 4777 树状数组+合数分解

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  5. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  6. Hdu 5452 Minimum Cut (2015 ACM/ICPC Asia Regional Shenyang Online) dfs + LCA

    题目链接: Hdu 5452 Minimum Cut 题目描述: 有一棵生成树,有n个点,给出m-n+1条边,截断一条生成树上的边后,再截断至少多少条边才能使图不连通, 问截断总边数? 解题思路: 因 ...

  7. HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

    HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意:  给一个序列由 ...

  8. HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number                         ...

  9. HDU 1394 Minimum Inversion Number(线段树/树状数组求逆序数)

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

随机推荐

  1. Docker-Compose练习

    运行一个镜像,需要添加大量的参数. 可以通过Docker-Compose编写这些参数. Docker-Compose可以帮助我们批量的管理容器. 只需要通过一个docker-compose.yml文件 ...

  2. Java反编译反混淆神器 - CFR

    最近有大量jar包需要反编译后使用,但是由于jar包中的类被混淆过了,直接反编译以后的里面所有的变量都是一个名字.所以这里介绍一个反混淆神器:CRF. 不知道是不是官网的链接:http://www.b ...

  3. 【Redis3.0.x】事务

    Redis3.0.x 事务 基本概念 multi,exec,discard,watch 是 Redis 事务的基础,它们允许一步执行一组命令,有两个重要保证: 事务中的所有命令都被序列化并顺序执行.在 ...

  4. 牺牲速度来节省内存,Redis是觉得自己太快了吗

    前言 正常情况下我们选择使用 Redis 就是为了提升查询速度,然而让人意外的是,Redis 当中却有一种比较有意思的数据结构,这种数据结构通过牺牲部分读写速度来达到节省内存的目的,这就是 zipli ...

  5. ansible 安装和使用

                                ansible 安装和使用   ## 安装epel 源: rpm -ivh https://dl.fedoraproject.org/pub/e ...

  6. Log4j配置按照文件大小和日期分割日志文件

    目录 Log4j 下载地址 文件大小分割日志文件 以日期分割每天产生一个日志文件 自定义信息输出到日志文件 Log4j 下载地址 Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控 ...

  7. 【Web】HTML入门小结

    文章目录 HTML? HTML 初识元素/标签 HTML语义化标签 标题 段落 font HTMl链接 HTML图像 HTML列表 HTML div HTML 块级元素与行内元素 HTML常用带格式作 ...

  8. LeetCode563. 二叉树的坡度

    题目 1 class Solution { 2 public: 3 int ans = 0; 4 int findTilt(TreeNode* root) { 5 postOrder(root); 6 ...

  9. 超详细 安装VMware Workstation,并安装WIN10操作系统连接外网 步骤指导

    首先下载VMware Workstation15.1版本,我保存在迅雷链接里面,下载速度非常可观. 链接:https://pan.xunlei.com/s/VMRSt6hHMZXEmPZCm6gJcG ...

  10. hive窗口函数/分析函数详细剖析

    hive窗口函数/分析函数 在sql中有一类函数叫做聚合函数,例如sum().avg().max()等等,这类函数可以将多行数据按照规则聚集为一行,一般来讲聚集后的行数是要少于聚集前的行数的.但是有时 ...