hihoCoder #1449 : 后缀自动机三·重复旋律6
题目链接
时间限制:15000ms
单点时限:3000ms
内存限制:512MB
描述
小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一个音乐旋律被表示为一段数构成的数列。
现在小Hi想知道一部作品中所有长度为K的旋律中出现次数最多的旋律的出现次数。但是K不是固定的,小Hi想知道对于所有的K的答案。
输入
共一行,包含一个由小写字母构成的字符串S。字符串长度不超过 1000000。
输出
共Length(S)行,每行一个整数,表示答案。
样例输入
aab
样例输出
2
1
1
思路
后缀自动机板子
求相同长度字符串出现次数最多的字符串出现的次数
- 利用endpos的长度求解,每个endpos对应长度 minlen 到 maxlen的字符串,当我们知道所有的endpos之后,又因为ans[N]单调递减,我们只需要维护maxlen对应的长度,从最后开始先前扫一遍更新max ans
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 1e6+6;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
// __int128 read() { __int128 x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); } return x * f;}
// void print(__int128 x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) print(x / 10); putchar(x % 10 + '0');}
char s[maxn];
struct SAM{int trans[maxn<<1][26], slink[maxn<<1], maxlen[maxn<<1];// 用来求endposint indegree[maxn<<1], endpos[maxn<<1], rank[maxn<<1], ans[maxn<<1];int last, now, root, len;inline void newnode (int v) {maxlen[++now] = v;}inline void extend(int c) {newnode(maxlen[last] + 1);int p = last, np = now;// 更新transwhile (p && !trans[p][c]) {trans[p][c] = np;p = slink[p];}if (!p) slink[np] = root;else {int q = trans[p][c];if (maxlen[p] + 1 != maxlen[q]) {// 将q点拆出nq,使得maxlen[p] + 1 == maxlen[q]newnode(maxlen[p] + 1);int nq = now;memcpy(trans[nq], trans[q], sizeof(trans[q]));slink[nq] = slink[q];slink[q] = slink[np] = nq;while (p && trans[p][c] == q) {trans[p][c] = nq;p = slink[p];} }else slink[np] = q;}last = np;// 初始状态为可接受状态endpos[np] = 1;}inline void build() {scanf("%s", s);len = strlen(s);root = last = now = 1;for (int i = 0; i < len; ++i) extend(s[i] - 'a');}// 拓扑排序inline void topsort() {for (int i = 1; i <= now; ++i) indegree[ maxlen[i] ]++; // 统计相同度数的节点的个数for (int i = 1; i <= now; ++i) indegree[i] += indegree[i-1]; // 统计度数小于等于 i 的节点的总数for (int i = 1; i <= now; ++i) rank[ indegree[ maxlen[i] ]-- ] = i; // 为每个节点编号,节点度数越大编号越靠后// 从下往上按照slik更新for (int i = now; i >= 1; --i) {int x = rank[i];endpos[slink[x]] += endpos[x];}}// 求不同的子串种类inline LL all () {LL ans = 0;for (int i = root+1; i <= now; ++i) {ans += maxlen[i] - maxlen[ slink[i] ];}return ans;}// 长度为K的字符串有多种,求出现次数最多的次数inline void get_maxk() {topsort();for (int i = 1; i <= now; ++i) {ans[maxlen[i]] = max(ans[maxlen[i]], endpos[i]);}for (int i = len; i >= 1; --i) ans[i] = max(ans[i], ans[i+1]);for (int i = 1; i <= len; ++i) //cout << ans[i] << endl; printf("%d\n", ans[i]);}}sam;int main() {#ifndef ONLINE_JUDGE// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);
#endifios::sync_with_stdio(false);cin.tie(0); cout.tie(0);sam.build();sam.get_maxk();return 0;
}
hihoCoder #1449 : 后缀自动机三·重复旋律6相关推荐
- hihocoder 1449 : 后缀自动机三·重复旋律6(后缀自动机)
#1449 : 后缀自动机三·重复旋律6 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数 ...
- hihocoder 1465 : 后缀自动机五·重复旋律8(后缀自动机+最长公共子串)
1465 : 后缀自动机五·重复旋律8 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的 ...
- hihocoder 1457 : 后缀自动机四·重复旋律7(后缀自动机+拓扑序BFS)
#1457 : 后缀自动机四·重复旋律7 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成 ...
- hihoCoder #1457 : 后缀自动机四·重复旋律7
题目链接 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的是小Hi发现了一部名字叫<十进制进行曲大全>的作品集,顾名思义,这部作品集里 ...
- hihoCoder #1445 : 后缀自动机二·重复旋律5
描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi想知道一部作品中出现了多少不同的旋律? 输入 共一行,包含一个由小写字母构成的字符串.字符串长度不 ...
- HihoCoder - 1465 后缀自动机五·重复旋律8(后缀自动机)
题目链接:点击查看 题目大意:给出一个模式串,在给出多个匹配串,问每个匹配串与其"循环相似旋律"的字符串,在模式串中出现的总次数,"循环相似旋律"指的是一个字符 ...
- HihoCoder - 1457 后缀自动机四·重复旋律7(后缀自动机)
题目链接:点击查看 题目大意:给出 n 个由 0~9 的数字组成的字符串,现在要求每个子串所表示的十进制下数字的累加之和 题目分析:因为对于字符串的所有子串而言数量无疑是非常庞大的,所以我们选择用后缀 ...
- HihoCoder - 1445 后缀自动机二·重复旋律5(后缀自动机)
题目链接:点击查看 题目大意:给出一个字符串 s ,求 s 中本质不同的子串的数量 题目分析:因为 s 的长度给到了 1e6 ,用后缀数组可能会超时,所以最好的方法肯定是用后缀自动机来做,因为每个节点 ...
- hihocoder #1465 : 后缀自动机五·重复旋律8
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 小Hi发现旋律可以循环,每次把一 ...
最新文章
- 如何设计一个本地缓存
- LVDS 相关功能调式
- 项目经理这些技能,是项目成功的关键保障
- boost::core模块default_allocator
- 使用logdashboard进行可视化的日志追踪
- LeetCode 104二叉树的最大深度-简单
- python怎么看内置模块_Python的内置模块详解
- 美团数据仓库-数据脱敏
- 如何启用“锁定内存页”选项 (Windows)
- shell中设置文字输出的颜色及字体格式
- linux 小度 驱动_Linux硬链接和软链接
- asp access服装商城计算机设计网站作品
- cygwin下各盘挂载点
- 基于数值数据理解和重要信息验证的数据到文本生成模型
- JS等比例缩小图片尺寸
- JQMeter进度条动态加载演示
- Android 开机logo支持的格式
- 下载微信小程序中音频的方法和路径
- Jedis远程连接阿里云 Failed to create socket
- 技术资源分享(更新中)
热门文章
- Eclipse中tomcat更改部署路径 deply path
- [Java5新特性]	动态代理
- [Python人工智能] 二十一.Word2Vec+CNN中文文本分类详解及与机器学习(RF\DTC\SVM\KNN\NB\LR)分类对比
- iOS之深入解析内存管理NSTimer的强引用问题
- OpenGL之利用矩阵的“平移”“旋转”“综合变换”等实现矩形的移动
- 王牌之作 特斯拉国产Model Y明年初下线
- Django 模型 —— 模型介绍
- 使用pytz模块进行时区转换及时间计算
- 《数据库原理与应用》(第三版) 第4章SQL Server 2012基础 习题参考答案
- ubuntu下安装并配置VIM编辑器