工艺(SAM)

传送门

用SAM可以非常轻松的解决问题。

只要把原串向SAM中插入两次,之后直接从\(t_0\)状态开始每次贪心跑最小就可以了。

因为这个题要用map,所以之前取begin即可。

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define rep(i,a,n) for(register int i = a;i <= n;i++)
#define per(i,n,a) for(register int i = n;i >= a;i--)
#define enter putchar(‘\n‘)
#define pr pair<int,int>
#define mp make_pair
#define fi first
#define sc second
using namespace std;
typedef long long ll;
const int M = 600005;
const int N = 10000005;

int read()
{
    int ans = 0,op = 1;char ch = getchar();
    while(ch < ‘0‘ || ch > ‘9‘) {if(ch == ‘-‘) op = -1;ch = getchar();}
    while(ch >=‘0‘ && ch <= ‘9‘) ans = ans * 10 + ch - ‘0‘,ch = getchar();
    return ans * op;
}

int n,a[M],b[M];

struct SuffixAutomaton
{
    int last,cnt,l[M<<1],fa[M<<1];
    map<int,int> ch[M<<1];
    void extend(int c)
    {
        int p = last,np = ++cnt;
        last = np,l[np] = l[p] + 1;
        while(p && !ch[p].count(c)) ch[p][c] = np,p = fa[p];
        if(!p) fa[np] = 1;
        else
        {
            int q = ch[p][c];
            if(l[p] + 1 == l[q]) fa[np] = q;
            else
            {
                int nq = ++cnt;
                l[nq] = l[p] + 1,ch[nq] = ch[q];
                fa[nq] = fa[q],fa[q] = fa[np] = nq;
                while(ch[p][c] == q) ch[p][c] = nq,p = fa[p];
            }
        }
    }
    void find()
    {
        int cur = 1;
        rep(i,1,n) printf("%d ",ch[cur].begin()->fi),cur = ch[cur].begin()->sc;
    }
}SAM;

int main()
{
    n = read();
    rep(i,1,n) a[i] = read();
    SAM.last = SAM.cnt = 1;
    rep(i,1,n) SAM.extend(a[i]);
    rep(i,1,n) SAM.extend(a[i]);
    SAM.find();
    return 0;
}

原文地址:https://www.cnblogs.com/captain1/p/10261021.html

时间: 2024-08-03 06:30:35

工艺(SAM)的相关文章

【BZOJ2882】工艺 [SAM]

工艺 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 小敏和小燕是一对好朋友. 他们正在玩一种神奇的游戏,叫Minecraft. 他们现在要做一个由方块构成的长条工艺品.但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边. 他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮. 两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样那么谁的瑕疵

【BZOJ2882】工艺(后缀自动机)

[BZOJ2882]工艺(后缀自动机) 题面 BZOJ权限题,良心洛谷 题解 还是一样的,先把串在后面接一遍 然后构建\(SAM\) 直接按照字典序输出\(n\)次就行了 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #incl

P1368 工艺

题目 P1368 工艺 你好水题 做法 备份一下原数组,然后插入,直接输出贪心每位最小的就好了 My complete code 再见水题 #include<map> #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<string> using namespace std; typedef int LL; const L

后缀自动机(SAM) 合集

先上模板 int len[maxn << 1],fa[maxn << 1],son[maxn << 1][maxc]; LL num[maxn << 1]; int size,last; void Init(){ size = last = 1; } void insert(char c){ int s = c - 'a'; int p = last,np = ++size;last = np; num[np] = 1; //主链结点出现次数 + 1 len

sam 文件的解释

高通两数据测序之后要map到基因组上,我通常用bwa bowtie和tophat .其实我知道sam 文件有好几个field,每个field代表不同的意思,但是由于各种格式的文件确实太多了,我也记不住每个field具体的意思.每次要用的时候都是上网再去找,或者把相关的资料下载下来,再现学. 今天,我和一个同学讨论我们数据的情况.他们都是用bowtie 去map 的,我之前写了个脚本,是用bwa 做的map,我有点懒散,也懒得再去修改了,于是也没想着要再写一个用bowtie 做map的脚本.与同学

SAM初探

SAM,即Suffix Automaton,后缀自动机. 关于字符串有很多玩法,有很多算法都是围绕字符串展开的.为什么?我的理解是:相较于数字组成的序列,字母组成的序列中每个单位上元素的个数是有限的.对于有限的东西,相较于无限的东西就会具有一些奇妙的性质.最简单的,就是序列扩展成的树每个节点的儿子数是有限的.所以根据这个,从字符串Hash,到KMP,再到Suffix Array,Suffix Automaton,纷纷诞生. 后缀数组在处理字符串上相当于一把好钢,他能应付在字符串的大多数问题.那么

【bzoj3926- [Zjoi2015]诸神眷顾的幻想乡】广义sam

题意:给定一棵树,每个节点有一个颜色,问树上有多少种子串(定义子串为某两个点上的路径),保证叶子节点数<=20.n<=10^5 题解: 叶子节点小于等于20,考虑将每个叶子节点作为根把树给提起来形成一棵trie,然后定义这棵树的子串为从上到下的一个串(深度从浅到深). 这样做我们可以发现每个子串必定是某棵trie上的一段直线.统计20棵树的不同子串只需要把它们建到一个自动机上就行了,相当于把20棵trie合并成一棵大的.对于每个节点x,它贡献的子串数量是max[x]-min[x],又因为min

TOPCODER SAM 686 div1 300

// TOPCODER SAM 686 div1 300 Problem Statement 带有小中括号的括号序列,问可以去掉多少子串,使得剩下的非空串是合法的. Constraints 字符串长度不超过 40. Examples // ans[i] = count(s[i]) string s[] = {"()[]", "())", "()()", "([)]", "())[]][]([]()]]()]]]&qu

画册制作尺寸纸张工艺推荐

企业画册制作推荐尺寸A4(210mm*285mm) 纸张建议封面250g铜版纸/内页157g铜版纸 高档画册印后工艺推荐封面覆膜,24P(12页纸)以内可以骑马钉装订,24P以上建议用锁线胶装. 其他尺寸画册介绍: 方形画册尺寸210mm*210mm,A5尺寸画册140mm*210mm,特殊尺寸可以定制. 画册纸张选择: 纸张比较厚实的可以选择封面250g(覆膜)/内页200g或250g铜版纸,产品手册说明书纸张一般比较薄,可以选择封面157g/内页105g铜版纸,高档企业画册可选择特种纸做封面