Corporate Identity poj3450

来源:互联网 发布:java怎么计算时间差 编辑:程序博客网 时间:2024/05/16 18:30

SAM和SA都可以搞,练习一下SAM输出答案。

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <cstring>#include <stack>#include <cctype>#include <utility>   #include <map>#include <string>  #include <climits> #include <set>#include <string>    #include <sstream>#include <utility>   #include <ctime>#include <bitset>using std::priority_queue;using std::vector;using std::swap;using std::stack;using std::sort;using std::max;using std::min;using std::pair;using std::map;using std::string;using std::cin;using std::cout;using std::set;using std::queue;using std::string;using std::stringstream;using std::make_pair;using std::getline;using std::greater;using std::endl;using std::multimap;using std::deque;using std::unique;using std::lower_bound;using std::random_shuffle;using std::bitset;typedef long long LL;typedef unsigned long long ULL;typedef pair<int, int> PAIR;typedef multimap<int, int> MMAP;typedef LL TY;const int MAXN(210);const int MAXM(50010);const int MAXE(100010);const int MAXK(6);const int HSIZE(131313);const int SIGMA_SIZE(26);const int MAXH(19);const int INFI((INT_MAX-1) >> 1);const ULL BASE(31);const LL LIM(10000000);const int INV(-10000);const LL MOD(1000000007);const double EPS(1e-7);template<typename T> void checkmax(T &a, T b){if(b > a) a = b;}template<typename T> void checkmin(T &a, T b){if(b < a) a = b;}template<typename T> T ABS(const T &a){return a < 0? -a: a;}int cnt[MAXN];int buc[MAXN << 1];char str0[MAXN];char str[MAXN];struct SAM{struct NODE{int len, right;int rec1, rec2;NODE *f, *ch[SIGMA_SIZE];};NODE *root, *last;NODE pool[MAXN << 1];int size;void init(){root = last = pool;root->f = 0;root->len = 0;root->rec1 = root->rec2 = 0;memset(root->ch, 0, sizeof(root->ch));size = 1;}NODE *newnode(int tl){pool[size].len = tl;pool[size].rec1 = 0;pool[size].rec2 = tl;memset(pool[size].ch, 0, sizeof(pool[size].ch));return pool+size++;}void extend(int id){NODE *p = last, *np = newnode(last->len+1);np->right = np->len;last = np;while(p && p->ch[id] == 0)p->ch[id] = np, p = p->f;if(p == 0)np->f = root;else{NODE *q = p->ch[id];if(p->len+1 == q->len)np->f = q;else{NODE *nq = newnode(p->len+1);memcpy(nq->ch, q->ch, sizeof(nq->ch));nq->right = q->right;nq->f = q->f;q->f = np->f = nq;while(p && p->ch[id] == q)p->ch[id] = nq, p = p->f;}}}void tupo(){int tlen = last->len;memset(cnt, 0, sizeof(cnt[0])*(tlen+1));for(int i = 0; i < size; ++i) ++cnt[pool[i].len];for(int i = 1; i <= tlen; ++i) cnt[i] += cnt[i-1];for(int i = 0; i < size; ++i) buc[--cnt[pool[i].len]] = i;}void solve(int n){for(int i = 1; i < n; ++i){scanf("%s", str);NODE *p = root;int tl = 0;for(char *sp = str; *sp; ++sp){int id = *sp-'a';if(p->ch[id]){++tl;p = p->ch[id];}else{while(p && p->ch[id] == 0) p = p->f;if(p){tl = p->len+1;p = p->ch[id];}else{p = root;tl = 0;}}checkmax(p->rec1, tl);}for(int i = size-1; i > 0; --i){p = pool+buc[i];checkmin(p->rec2, p->rec1);if(p->rec1) p->f->rec1 = p->f->len;p->rec1 = 0;}}int ans = 0;for(int i = 0; i < size; ++i)checkmax(ans, pool[i].rec2);if(ans == 0){printf("IDENTITY LOST\n");return;}int ind = -1;for(int i = 0; i < size; ++i)if(pool[i].rec2 == ans){if(ind == -1 || strncmp(str0+pool[i].right-ans, str0+ind, ans) < 0)ind = pool[i].right-ans;}for(int i = 0; i < ans; ++i)printf("%c", str0[ind+i]);printf("\n");}} sam;int main(){int n;while(scanf("%d", &n), n){sam.init();scanf("%s", str0);for(char *sp = str0; *sp; ++sp)sam.extend(*sp-'a');sam.tupo();sam.solve(n);}return 0;}