標籤:
把串S複製成SS然後扔進尾碼自動機裡, 從根選最小的兒子走, 走N步就是答案了...一開始還想寫個treap的...後來覺得太麻煩..就用map了...
---------------------------------------------------------------------------
#include<cstdio>#include<cstring>#include<algorithm>#include<map> using namespace std; const int maxn = 300009; struct Node {Node* fa;map<int, Node*> ch;int len;} pool[maxn << 2], *pt = pool, *root, *last; Node* newNode(int v) {pt->fa = NULL;pt->ch.clear();pt->len = v;return pt++;} void init() {pt = pool;root = last = newNode(0);} void Extend(int c) {Node *p = last, *np = newNode(p->len + 1);for(; p && !p->ch[c]; p = p->fa)p->ch[c] = np;if(!p)np->fa = root;else {Node* q = p->ch[c];if(p->len + 1 == q->len)np->fa = q;else {Node* nq = newNode(p->len + 1);nq->fa = q->fa;q->fa = np->fa = nq;for(map<int, Node*>::iterator it = q->ch.begin(); it != q->ch.end(); it++)nq->ch[it->first] = it->second;for(; p && p->ch[c] == q; p = p->fa)p->ch[c] = nq;}}last = np;} int N, num[maxn]; int main() {init();scanf("%d", &N);for(int i = 0; i < N; i++)scanf("%d", num + i);for(int i = 0; i < 2; i++)for(int j = 0; j < N; j++)Extend(num[j]);for(int i = 0; i < N; i++) {map<int, Node*>::iterator it = root->ch.begin();if(i) putchar(‘ ‘);printf("%d", it->first);root = it->second;}return 0;}
---------------------------------------------------------------------------
2882: 工藝Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 268 Solved: 108
[Submit][Status][Discuss]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 2HINT
【資料規模與約定】
對於20%的資料,n<=1000
對於40%的資料,n<=10000
對於100%的資料,n<=300000
Source
BZOJ 2882: 工藝( 尾碼自動機 )