Description
小敏和小燕是一对好朋友。
他们正在玩一种神奇的游戏,叫Minecraft。
他们现在要做一个由方块构成的长条工艺品。但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边。
他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮。
两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样那么谁的瑕疵度小,那么谁就更漂亮,如果一样那么继续比较第i+1个方块。如果全都一样,那么这两个工艺品就一样漂亮。
Solution
经典的最小循环串问题,具体可以看WJMZBMR的冬令营讲稿orz
将串复制一遍再丢进SAM,数字比较大,用std::map
存子节点。
然后从根节点开始遍历,每次按字典序最小来走,由于是用map
存的,所以可以比较方便找到最小的儿子。
Code
/**************************************
* Au: Hany01
* Prob: [BZOJ2882] 工艺
* Date: Apr 25th, 2018
* Email: hany01@foxmail.com
**************************************/
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
#define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define rep(i, j) for (register int i = 0, i##_end_ = j; i < i##_end_; ++ i)
#define For(i, j ,k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define SZ(a) ((int)(a.size()))
#define ALL(a) a.begin(), a.end()
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define x first
#define y second
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define Mod (1000000007)
#define y1 wozenmezhemecaia
#ifdef hany01
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define debug(...)
#endif
template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
inline int read() {
register char c_; register int _, __;
for (_ = 0, __ = 1, c_ = getchar(); !isdigit(c_); c_ = getchar()) if (c_ == '-') __ = -1;
for ( ; isdigit(c_); c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
return _ * __;
}
const int maxn = 300005;
//
struct SAM
{
int fa, len;
map<int, int> ch;
}t[maxn << 2];
int tot = 1, las = 1;
inline void extend(int c)
{
register int np = ++ tot, p = las;
las = np, t[np].len = t[p].len + 1;
while (!t[p].ch[c] && p) t[p].ch[c] = np, p = t[p].fa;
if (!p) t[np].fa = 1;
else {
register int q = t[p].ch[c];
if (t[q].len == t[p].len + 1) t[np].fa = q;
else {
register int nq = ++ tot;
t[nq] = t[q], t[nq].len = t[p].len + 1;
t[q].fa = t[np].fa = nq;
while (p && t[p].ch[c] == q) t[p].ch[c] = nq, p = t[p].fa;
}
}
}
//
int main()
{
#ifdef hany01
File("bzoj2882");
#endif
//Statement
static int n, a[maxn];
//Init
n = read();
For(i, 1, n) extend(a[i] = read());
For(i, 1, n) extend(a[i]);
//Calc
for (static int T = n, u = 1; T --; )
printf("%d%c", (*t[u].ch.begin()).x, T ? ' ' : '\n'),
u = (*t[u].ch.begin()).y;
return 0;
}