[BZOJ2882]2882: 工艺

工艺

Description
小敏和小燕是一对好朋友。
他们正在玩一种神奇的游戏,叫Minecraft。
他们现在要做一个由方块构成的长条工艺品。但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边。
他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮。
两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样那么谁的瑕疵度小,那么谁就更漂亮,如果一样那么继续比较第i+1个方块。如果全都一样,那么这两个工艺品就一样漂亮。
Input
第一行两个整数n,代表方块的数目。
第二行n个整数,每个整数按从左到右的顺序输出方块瑕疵度的值。
Output
一行n个整数,代表最美观工艺品从左到右瑕疵度的值。
Sample Input
10
10 9 8 7 6 5 4 3 2 1
Sample Output
1 10 9 8 7 6 5 4 3 2
HINT
【数据规模与约定】
对于20%的数据,n<=1000
对于40%的数据,n<=10000
对于100%的数据,n<=300000

Code

#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = (l); i <= (r); i++)
#define per(i, r, l) for (int i = (r); i >= (l); i--)
#define REP(i, n) for (int i = 0; i < (n); i++)
#define PER(i, n) for (int i = (n)-1; i; i--)
#define MS(_) memset(_, 0, sizeof(_))
#define MP make_pair
#define PB push_back
typedef long long ll;
template<typename T> inline void read(T &x){
    x = 0; T f = 1; char ch = getchar();
    while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
    while (isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
    x *= f;
}

const int MaxN = 1200010;
int len[MaxN], n, a[MaxN], fa[MaxN];
map<int, int> nxt[MaxN];
struct SAM{
    int root, last, cnt;
    SAM(){ root = last = ++cnt; }
    inline void ins(int c){
        int np = ++cnt, p = last; last = np;
        len[np] = len[p] + 1;
        for (; p && !nxt[p][c]; nxt[p][c] = np, p = fa[p]);
        if (!p) fa[np] = root;
        else if (len[nxt[p][c]] == len[p] + 1) fa[np] = nxt[p][c];
        else{
            int nq = ++cnt, q = nxt[p][c]; len[nq] = len[p] + 1;
            nxt[nq] = nxt[q]; fa[nq] = fa[q];
            fa[np] = fa[q] = nq;
            for (; p && nxt[p][c] == q; nxt[p][c] = nq, p = fa[p]);
        }
    }
    inline void build(){
        read(n);
        rep(i, 1, n) read(a[i]), ins(a[i]);
        rep(i, 1, n) ins(a[i]);
    }
    inline void solve(){
        int now = root;
        rep(i, 1, n){
            map<int, int> :: iterator it = nxt[now].begin();
            printf("%d%c", it->first, i == n ? '\n' : ' ');
            now = it->second;
        }
    }
}sam;
int main(){
    sam.build();
    sam.solve();
    return 0;
}

你可能感兴趣的:(后缀自动机)