$ \color{#0066ff}{ 题目描述 }$

半月的夜空中,寄托了多少人与人之间的思念啊

曦月知道,这些思念会汇集成一个字符串\(S(n = |S|)\)

由于思念汇集的过于复杂,因此曦月希望提炼出所有的思念

我们定义\(Y_S(i)\)表示对于字符串\(S\)而言,长度为\(i\)的子串中,字典序最小的,左端点最小的左端点的值

比如对于串\(S = "baa"\),\(Y_S(1) = 2, Y_S(2) = 2, Y_S(3) = 1\)

曦月会告知你\(S\)串,你只需要告诉曦月\(Y_S(i)(1 \le i \le n)\)即可

\(\color{#0066ff}{输入格式}\)

第一行,两个参数,分别是\(\sigma \in \{10, 26, 10^7\}\)和\(n\)

如果\(\sigma = 26\),那么第二行将是一个长为\(n\)的小写字母字符串\(S\)

其他情况下,第二行将输入\(n\)个位于\([0, \sigma]内\)的整数

\(\color{#0066ff}{输出格式}\)

输出一行,第iii个数表示\(Y_S(i)\)的值

\(\color{#0066ff}{输入样例}\)

26 11
remoonqaqac26 11
txdydkwqaqa10000000 17
9 9 8 2 4 4 3 5 3 1 9 2 6 0 8 1 7

\(\color{#0066ff}{输出样例}\)

8 10 8 8 2 2 2 2 2 2 19 9 9 5 5 5 5 3 3 1 114 14 14 14 10 10 10 10 4 4 4 4 4 4 3 2 1

\(\color{#0066ff}{数据范围与提示}\)

\(\color{#0066ff}{题解}\)

建立后缀自动机,要求左端点最小,你需要维护左端点,所以倒着插入,建立后缀树

这样树上的点代表的是某一后缀的前缀

后缀自动机上每个点维护一个pos为起始位置l

然后考虑后缀树上的一条边,它对应的字串长度就是$[父亲len+1,自己的len] $,那么对于这一区间的答案就可以用自己子树的pos最小值来更新

至于字典序最小?,我们可以dfs出后缀树中每个节点是它父亲的那个儿子,然后考虑倒着覆盖,当前字典序是最优的,把原来的覆盖掉,用线段树维护答案就行了

#include<bits/stdc++.h>
#define LL long long
LL in() {char ch; LL x = 0, f = 1;while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));return x * f;
}
const int maxn = 3e5 + 10;
const int inf = 0x7fffffff;
struct Tree {protected:struct node {node *ch[2];int l, r, val, tag;node(int l = 0, int r = 0, int val = 0, int tag = -1): l(l), r(r), val(val), tag(tag) {ch[0] = ch[1] = NULL;}void trn(int v) { val = tag = v; }void dwn() {if(tag == -1) return;ch[0]->trn(tag);ch[1]->trn(tag);tag = -1;}int mid() { return (l + r) >> 1; }}*root;void build(node *&o, int l, int r) {o = new node(l, r);if(l == r) return;build(o->ch[0], l, o->mid());build(o->ch[1], o->mid() + 1, r);}void lazy(node *o, int l, int r, int val) {if(l > r) return;if(l <= o->l && o->r <= r) return o->trn(val);o->dwn();if(l <= o->mid()) lazy(o->ch[0], l, r, val);if(r > o->mid()) lazy(o->ch[1], l, r, val);}void out(node *o) {if(o->l == o->r) return (void)(printf("%d ", o->val));o->dwn();out(o->ch[0]); out(o->ch[1]);}public:void build(int n) { build(root, 1, n); }void lazy(int l, int r, int val) { lazy(root, l, r, val); }void out() { out(root); }
}tree;
struct SAM {protected:struct node {std::map<int, node*> ch, treech;node *fa;int len, pos;node(int len = 0, int pos = 0): len(len), pos(pos) { fa = NULL;ch.clear(), treech.clear();}}pool[maxn << 1], *tail, *root, *lst;int s[maxn];char ls[maxn];void extend(int c, int id) {node *o = new(tail++) node(lst->len + 1, id), *v = lst;for(; v && !v->ch[c]; v = v->fa) v->ch[c] = o;if(!v) o->fa = root;else if(v->len + 1 == v->ch[c]->len) o->fa = v->ch[c];else {node *n = new(tail++) node(v->len + 1, v->ch[c]->pos), *d = v->ch[c];n->ch = d->ch, n->fa = d->fa, d->fa = o->fa = n;for(; v && v->ch[c] == d; v = v->fa) v->ch[c] = n;}lst = o;}void getmin(node *o) {for(std::pair<int, node*> i : o->treech) {getmin(i.second);o->pos = std::min(o->pos, i.second->pos);}}void getans(node *o) {tree.lazy((o->fa? o->fa->len + 1 : 1), o->len, o->pos);for(std::map<int, node*>::reverse_iterator it = o->treech.rbegin(); it != o->treech.rend(); it++)getans(it->second);}public:SAM() {tail = pool;root = lst = new(tail++) node();}void init(int bel, int len) {if(bel == 26) {scanf("%s", ls + 1);for(int i = 1; i <= len; i++) s[i] = ls[i] - 'a';}else {for(int i = 1; i <= len; i++) s[i] = in();}for(int i = len; i >= 1; i--) extend(s[i], i); }void build() { for(node *o = pool + 1; o != tail; o++)o->fa->treech[s[o->pos + o->fa->len]] = o;}void getmin() { getmin(root); }void getans() { getans(root); }
}s;
int main() {int val = in(), n = in();s.init(val, n);tree.build(n);s.build();s.getmin();s.getans();tree.out();return 0;
}

转载于:https://www.cnblogs.com/olinr/p/10580458.html

P5108 仰望半月的夜空 SAM+线段树覆盖相关推荐

  1. 洛谷 P5108 仰望半月的夜空 解题报告

    P5108 仰望半月的夜空 题目描述 半月的夜空中,寄托了多少人与人之间的思念啊 曦月知道,这些思念会汇集成一个字符串\(S(n = |S|)\) 由于思念汇集的过于复杂,因此曦月希望提炼出所有的思念 ...

  2. CF1037H Security——SAM+线段树合并

    又是一道\(SAM\)维护\(endpos\)集合的题,我直接把CF700E的板子粘过来了QwQ 思路 如果我们有\([l,r]\)对应的\(SAM\),只需要在上面贪心就可以了.因为要求的是字典序比 ...

  3. P4770-[NOI2018]你的名字【SAM,线段树合并】

    正题 题目链接:https://www.luogu.com.cn/problem/P4770 题目大意 给出一个长度为nnn的字符串SSS.qqq次询问给出一个串TTT和一个区间[L,R][L,R][ ...

  4. CF700E-Cool Slogans【SAM,线段树合并,dp】

    正题 题目链接:https://www.luogu.com.cn/problem/CF700E 题目大意 给出一个字符串SSS,求一个最大的kkk使得存在kkk个字符串其中s1s_1s1​是SSS的子 ...

  5. 洛谷P4482 [BJWC2018]Border 的四种求法 字符串,SAM,线段树合并,线段树,树链剖分,DSU on Tree...

    原文链接https://www.cnblogs.com/zhouzhendong/p/LuoguP4482.html 题意 给定一个字符串 S,有 q 次询问,每次给定两个数 L,R ,求 S[L.. ...

  6. 2021CCPC华为云挑战赛:HDU 7091 重叠的子串(SAM + 线段树合并)

    重叠的子串 给定一个长度为n(1≤∣s∣≤105)n(1 \le \mid s \mid \le 10 ^ 5)n(1≤∣s∣≤105)的只由小写字母构成的字符串sss,有m,(1≤m≤106)m, ...

  7. CF666E-Forensic Examination【广义SAM,线段树合并】

    正题 题目链接:https://www.luogu.com.cn/problem/CF666E 解题思路 给出一个串SSS和nnn个串TiT_iTi​.mmm次询问Sa∼bS_{a\sim b}Sa∼ ...

  8. YbtOJ#532-往事之树【广义SAM,线段树合并】

    正题 题目链接:https://www.ybtoj.com.cn/problem/532 题目大意 给出nnn个点的一个TrieTrieTrie树,定义SxS_xSx​表示节点xxx代表的字符串 求m ...

  9. CF204E-Little Elephant and Strings【广义SAM,线段树合并】

    正题 题目链接:https://www.luogu.com.cn/problem/CF204E 题目大意 nnn个字符串的一个字符串集合,对于每个字符串求有多少个子串是这个字符串集合中至少kkk个字符 ...

最新文章

  1. 数学建模学习笔记——分类模型
  2. [导入]C#优化字符串操作【月儿原创】
  3. web javascript开发 之Response.Write 与document.writ...
  4. Linux之FTP服务、NFS服务、RPC服务及案例
  5. 模拟封装ajax,模拟jQ封装ajax,调用时出现Uncaught ReferenceError: param is
  6. 我的世界服务器怎么修改名称,我的世界端游怎么改名字
  7. openstack rabbitmq报错导致识别不到计算节点 解决方案
  8. 怎么用一套键鼠控制两个电脑
  9. Ubuntu零基础教学-Ubuntu下如何创建.txt记事本文件
  10. Git之(三)辅助命令
  11. 计算机的操作系统是什么与什么的接口,计算机中操作系统是什么的接口
  12. PHP语言是什么语言及能解决当下什么问题-动态更新
  13. 计算机网络复习-典型题目答案
  14. 【信息系统项目管理师】第二十二章 信息系统安全管理(考点汇总篇)
  15. IdentityServer3 v1文档
  16. Linux操作系统常见命令
  17. 怎样做竞品分析?竞品分析的意义?
  18. Redis进击(五)redis.conf 配置文件说明备注
  19. 深度学习 客流统计 人流计数
  20. python实现决策树-数据集如下图所示,根据我们对决策树的理解,设计一棵决策树,并输入{Age:36,Salary:H,STU:No,Credit:OK} 测试数据,是否与预期结果一致?

热门文章

  1. 杰理AC696N串口通信实验
  2. 统计员工业绩app_统计员工业绩app
  3. 【C语言】实现双人控制的战斗小游戏
  4. 虚拟语气用法总结及真题解析
  5. 我爬了某宝上4000+网店只为了告诉你中国人最爱喝什么绿茶
  6. 维修服务器bga是什么,BGA芯片元器件坏了怎么拆除焊死的BGA?
  7. Linux内核如何输出中文字符
  8. mysql innodb 数据打捞(二)innodb 页面打捞编程
  9. (10.1.4) Material Design设计规范
  10. c 递归实现谢宾斯基三角形