題意:給定n個字串,求乙個最長的子串至少在每個串中的不重疊出現次數都不小於2。輸出滿足條件的最長子串長度
思路:根據《字尾陣列——處理字串的有力工具》的思路,先將 n個字串連起來, 中間用不相同的且沒有出現在字串中的字元隔開, 求字尾陣列。 然後二分答案, 再將字尾分組。判斷的時候, 要看是否有一組字尾在每個原來的字串中至少出現兩次, 並且在每個原來的字串中, 字尾的起始位置的最大值與最小值之差是否不小於當前答案(判斷能否做到不重疊, 如果題目中沒有不重疊的要求, 那麼不用做此判斷) 。這個做法的時間複雜度為 0(nlogn) 。
#define _crt_secure_no_deprecate#include#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
typedef
long
long
intll;
const
int maxn = 10000 * 10 * 2
;int
wa[maxn], wb[maxn], wv[maxn], ws[maxn];
int cmp(int *r, int a, int b, int
l)void da(int *r, int *sa, int n, int
m)
return;}
intrank[maxn], height[maxn], sa[maxn];
void calheight(int *r, int *sa, int
n)
for (i = 0; i < n; height[rank[i++]] =k)
return;}
intr[maxn], len, n, t, index[maxn],vis[maxn];
char sub[10000+5
];struct
node
}node[
20];
bool check(int
x) memset(vis,
0, sizeof
(vis));
for (int i = 1; i < len; i++)
node[k].init();
}if (tot == n)//
n個串都滿足要求,說明長度x存在
tot = 0
;
break
; }
if (height[i] >=x)
if (!vis[i-1
]) }
else
node[k].init();
}if (tot == n) //
n個串都滿足要求,說明長度x存在
tot = 0
; }
}return
false;}
void
solve()
else
}printf(
"%d\n
", ans);
}int
main()
index[len] =i;
r[len++] =val;
}da(r, sa, len,
128);
calheight(r, sa, len - 1
); solve();
}//#ifdef local_time
//cout << "[finished in " << clock() - start << " ms]" << endl;
//#endif
return0;
}
字尾樹 字尾陣列
在字串處理當中,字尾樹和字尾陣列都是非常有力的工具,其中字尾樹大家了解得比較多,關於字尾陣列則很少見於國內的資料。其實字尾陣列是字尾樹的乙個非 常精巧的替代品,它比字尾樹容易程式設計實現,能夠實現字尾樹的很多功能而時間複雜度也不太遜色,並且,它比字尾樹所占用的空間小很多。可以說,在資訊學競賽 中字尾...
字尾樹 字尾陣列
我們考慮將乙個串的所有字尾插入乙個trie中,得到的trie就是字尾trie。我們可以發現,樹上有分叉或者是字尾節點的點的個數是o l en o len o len 個,這個後面解釋,於是把沒有分支並且不是字尾節點的點壓縮到一起,就變成了字尾樹。不難發現,字尾樹可以表示該字串的所有子串。下面分析一下...
字尾陣列入門,字尾陣列模板整理
我自己懶得寫,就是想寫個部落格儲存下大佬的部落格位址 點這模板題 大佬的模板 include include include include include include include include include include include define inf 0x3f3f3f3f d...