Relevant Phrases of Annihilation spoj220

来源:互联网 发布:姓名抽奖软件 编辑:程序博客网 时间:2024/06/05 05:20



多个字符串连接,此题注意不能重复即可


#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>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::istringstream;using std::make_pair;using std::getline;using std::greater;using std::endl;using std::multimap;typedef long long LL;typedef unsigned long long ULL;typedef pair<int, int> PAIR;typedef multimap<int, int> MMAP;const int MAXN(101000);const int SIGMA_SIZE(26);const int MAXM(110);const int MAXE(4000010);const int MAXH(18);const int INFI((INT_MAX-1) >> 2);const int MOD(9999991);const ULL LIM(1000000000000000ull);struct SA{int S[MAXN];int sa[MAXN], t1[MAXN], t2[MAXN], cnt[MAXN], len, M;void init(int tl, int tm = 128){len = tl;M = tm;int *p1 = t1, *p2 = t2;for(int i = 0; i < M; ++i) cnt[i] = 0;for(int i = 0; i <= len; ++i) ++cnt[p1[i] = S[i]];for(int i = 1; i < M; ++i) cnt[i] += cnt[i-1];for(int i = len; i >= 0; --i) sa[--cnt[p1[i]]] = i;int temp = 1;for(int k = 1; temp <= len; k <<= 1){temp = 0;for(int i = len-k+1; i <= len; ++i) p2[temp++] = i;for(int i = 0; i <= len; ++i)if(sa[i] >= k)p2[temp++] = sa[i]-k;for(int i = 0; i < M; ++i) cnt[i] = 0;for(int i = 0; i <= len; ++i) ++cnt[p1[p2[i]]];for(int i = 1; i < M; ++i) cnt[i] += cnt[i-1];for(int i = len; i >= 0; --i) sa[--cnt[p1[p2[i]]]] = p2[i];swap(p1, p2);temp = 1;p1[sa[0]] = 0;for(int i = 1; i <= len; ++i)p1[sa[i]] = p2[sa[i-1]] == p2[sa[i]] && p2[sa[i-1]+k] == p2[sa[i]+k]? temp-1: temp++;M = temp;}}int rank[MAXN], height[MAXN];void getHeight(){int k = 0;for(int i = 1; i <= len; ++i)rank[sa[i]] = i;for(int i = 0; i < len; ++i){if(k) --k;int j = sa[rank[i]-1];while(S[i+k] == S[j+k]) ++k;height[rank[i]] = k;}}};SA sa;int table[12];int N;int find(int tar){int l = 1, r = N+1, m;while(l < r){m = (l+r) >> 1;if(table[m] < tar)l = m+1;elser = m;}return l;}int flag[12], mi[12], mx[12], OK[12];bool check(int value){memset(flag, 0, sizeof(flag));memset(OK, 0, sizeof(OK));int ind = 0;int i, j;for(i = 0; i <= sa.len; i = j){j = i+1;++ind;int lb = find(sa.sa[i]), cnt = 0;if(table[lb]-sa.sa[i] >= value){flag[lb] = ind;mi[lb] = sa.sa[i];mx[lb] = sa.sa[i];}while(j <= sa.len && sa.height[j] >= value){lb = find(sa.sa[j]);if(OK[lb] != ind){if(flag[lb] == ind){mi[lb] = min(mi[lb], sa.sa[j]);mx[lb] = max(mx[lb], sa.sa[j]);if(mx[lb]-mi[lb] >= value){OK[lb] = ind;++cnt;}}else{flag[lb] = ind;mi[lb] = mx[lb] = sa.sa[j];}}++j;}if(cnt == N)return true;}return false;}char str[10010];int main(){int TC;scanf("%d", &TC);while(TC--){scanf("%d", &N);int len = 0, tlen, sep = 129;int l = 1, r = 10000;for(int i = 1; i <= N; ++i){scanf("%s", str);tlen = strlen(str);r = min(r, tlen);len += tlen;int j, k;for(j = len-tlen, k = 0; j < len; ++j, ++k)sa.S[j] = str[k];table[i] = len;if(i != N)sa.S[len++] = sep++;elsesa.S[len] = 0;}sa.init(len, 150);sa.getHeight();++r;while(l < r){int m = (l+r) >> 1;if(check(m))l = m+1;elser = m;}--l;printf("%d\n", l);}return 0;}


原创粉丝点击