P1368 工艺 SA/最小表示法】的更多相关文章

正解:SA/最小表示法 解题报告: 传送门! 听说正解是最小表示法,,,O(n)然后常数还挺小的,,, 但是我不会QAQ! 所以先写下SA的做法趴,,,等get了最小表示法再来写正解QAQ 就这种题算是比较套路的,,,首先看到是个环,显然就考虑到倍增? 然后就跑个SA 然后从小往大扫sa数组,如果当前位置是<=序列长度n的,就直接输出然后return就好 注意一下的是n因为倍增了,所以长度要*2,这里建议是直接*2然后在求完之后再/2,不然每次都要打n*2的很容易错,,, over,放下代码就好…
传送门 好的一道最小表示法的裸板,感觉跑起来贼快(写博客时评测速度洛谷第二),这里简单讲讲最小表示法的实现. 首先我们将数组复制一遍接到原数组队尾,然后维护左右指针分别表示两个即将进行比较的字符串的头尾.然后开始逐位比较,当两个字串同一位置的字符不同时,相对来说字符值较大的指针跳到失配下标的后面一位,如果此时两个指针重合,将其中一个加一.边界条件:两个指针中有一个值大于原数组长度. 代码如下: #include<bits/stdc++.h> #define N 300005 using nam…
O(nlogn)的做法十分显然,有三种可以做到O(nlogn)的:1.最容易的想法:把串扩展成两倍,然后跑一遍SA求后缀数组.2.求后缀同样也可以用SAM去求解,用map存一下.3.最暴力的方法:直接二分+hash比较第一位不同的. 其实这题想要让我们用最小表示法求解,然而我不会就来学一下.很容易发现这样一个规律,如果存在s[i+k]>s[j+k],那么s[i...i+k]开头的都不会是最小表示法开头,因为s[i...i+k]=s[j...j+k],所以从s[i...i+k]开头的串都会经过这里…
我写的O(nlogn)O(nlogn)O(nlogn)的SA 8000ms 被 O(n)O(n)O(n)的SAM 2800ms 和 O(n)O(n)O(n)的最小表示法 500ms 头都锤爆- CODE 贴上大常数选手的代码 #include<bits/stdc++.h> using namespace std; char cb[1<<15],*cs=cb,*ct=cb; #define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,…
最小表示法就是直接扫过去 后缀自动机就是每次找最字典序最小儿子输出 最小表示法 /* 最小表示法裸题, 我好像学过来着?? 怎么忘得这么干净 */ #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<iostream> #define ll long long #define M 300010 #define mmp make_pair u…
先说后缀自动机的做法. 直接把S串复制一遍成SS,然后建立后缀自动机,go边相当于在当前字符的后面插入,而son边可以看作在字符串前面加一个字符. 所以贪心的走字典序最小的边即可,而且根据后缀自动机的构建的性质,是一定可以走够len的,然后输出即可. 人生第一个后缀自动机的代码. #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<map&g…
题意:给定一个由小写字母组成的长度为 n 的字符串,首尾相连,可以从任意一个字符开始,顺时针或逆时针取这个串(长度为 n),求一个字典序最大的字符串的开始字符位置和顺时针或逆时针.如果有多个字典序最大的字符串,优先选择开始位置靠前的,如果开始位置相同,优先选择顺时针. 这种字符串的问题,第一反应是后缀数组,为了达到首尾相连的目的,所以先复制了一个两倍长的该字符串,然后再将串倒置,也弄成两倍长度,得到顺逆时针的两倍长的串,并对这两个字符串分别做后缀数组,得到 sa 数组(该串字典序第几小的后缀的开…
[题目分析] 一见到题目,就有了一个显而易见obviously的想法.只需要每次找到倒过来最小的那一个字符串翻转就可以了. 然而事情并不是这样的,比如说505023这样一个字符串,如果翻转了成为320505. 最小的后缀是05,那么得到的字符串是055023,然而最小的结果是全部翻转,为050523. 因为我们没有考虑到翻转后的字符和未翻转的字符有可能会连接起来,我们并没有考虑到连接部分对答案的影响. 这里我们用最小表示的方法来做这道题目,每次操作完成之后,都需要把翻转后的串复制两遍,这样的话,…
题目链接: Hdu 5442 Favorite Donut 题目描述: 给出一个文本串,找出顺时针或者逆时针循环旋转后,字典序最大的那个字符串,字典序最大的字符串如果有多个,就输出下标最小的那个,如果顺时针和逆时针的起始下标相同,则输出顺时针. 解题思路: 看到题目感觉后缀数组可以搞,正准备犯傻被队友拦下了,听队友解释一番,果断丢锅给队友.赛后试了一下后缀数组果然麻烦的不要不要的(QWQ),还是最大最小表示法 + KMP来的干净利索. 最大表示法:对于一个长度为len文本串,经过循环旋转得到长度…
题意:给你一串n个数,求出循环来看一阶差的最小字典序:数字串看成一个顺时针的环,从某一点开始顺时针循环整个环,保证字典序最小就是答案 例如给你 2 1 3 就会得到(1-2+8 注意题意负数需要加8) (3-1) (2-3+8)-> 7 2 7 答案就是2 7 7. 典型的最小表示法.线性时间内求出最小字典序. 首先复制一遍数字串在原串后面,这样从原串任意位置开始向再后n个位置就是答案.接着双指针维护,直接双指针暴力比较数字串,当出现不同数字时,就把字典序大的那个指针向后移动尽量多的位置这样可以…