題意:問連續重複部分最多的串是什麼,不能重疊,且我們要字典序最小的串如xbcabcab,有bcabca重複次數為2,cabcab重複次數也為2,那麼要前邊那個
思路:以前寫過乙個類似的,spoj 687,這個只是求連續重複部分最多的串的次數,並不需要將按字典序最小串輸出,那麼我們可以用到spoj687的**,用它我們可以求出那個重複的次數和滿足這個次數的串的長度,那麼就只差找到字典序最小的那個串了,而我們知道字尾陣列的sa陣列就是按字典序來的嘛,從字典序最小開始找,找到就跳出,輸出即可,如何判斷以sa[i]開始的滿不滿足呢,因為我們有了可以達到重複次數的長度,那麼列舉這個長度,在計算一次個數,與重複次數相同就滿足條件了
//// main.cpp
// 字尾陣列
//// created by liuzhe on 17/2/5.
//#include #include #include #include #include using namespace std;
//poj 3693
const int maxn = 100010;
int wa[maxn],wb[maxn],wv[maxn],ww[maxn];
int sa[maxn],lcp[maxn],rank[maxn],rank1[maxn];
char str[maxn];
int t,nn;
int dp[maxn][20];
inline bool cmp(int *r,int a,int b,int len)
void construct_sa(int n,int m)
for(i=0;i=0;i--) sa[--ww[wv[i]]]=y[i];
for(t=x,x=y,y=t,x[sa[0]]=0,p=i=1;i0)
h--;
for(;j+hri)
swap(le,ri);
le++;
int k=0;
while((1<<(k+1))<=ri-le+1)
k++;
int ans2=min(dp[le][k],dp[ri-(1<=0&&t%len!=0)
if(rmq(pos,pos+len)>=(len-t%len))
sum++;
if(sum>ans) ans=sum;}}
for(int len=1;len<=n;len++)}}
return ans;
}int main()
{ int cas=1;
while(scanf("%s",str)!=-1)
{if(str[0]=='#')
break;
int len=strlen(str);
construct_sa(len,200);
construct_lcp(len);
rmq_init(len);
int ans=solve(len);
printf("case %d: ",cas++);
int pos=0,leng=0,flag=0;
for(int i=1;i<=len;i++)
{for(int j=0;j
POJ 3693 (重複次數最多連續重複子串)
上邊寫了個大致思路,然後看了kuangbin的部落格,深入的了解了一下怎麼做。只是還得注意一些地方 設目前詢問的長度為k,則答案顯然為k l 1,但這不一定是最好的。拿一組例子來說 xbcabcab 因為要達到n logn的複雜度,所以外迴圈模擬長度,內迴圈模擬從第幾個位置開始,但每次加的都是l 所...
字尾陣列練習3 連續重複子串
比前面兩個練習題更加簡單,只要知道height陣列的性質就可以了 poj2774 時間限制 1 sec 記憶體限制 128 mb 提交 101 解決 57 提交 狀態 討論版 命題人 admin 題目描述 不多說,這道題的思路我會引用羅穗騫大佬的 當中的講解 簡單來說,就是把兩個字串合併,然後用ge...
字尾陣列練習3 連續重複子串
比前面兩個練習題更加簡單,只要知道height陣列的性質就可以了 poj2774 時間限制 1 sec 記憶體限制 128 mb 提交 101 解決 57 提交 狀態 討論版 命題人 admin 題目描述 不多說,這道題的思路我會引用羅穗騫大佬的 當中的講解 簡單來說,就是把兩個字串合併,然後用ge...