poj 3693連續重複最多的串

2021-07-27 06:53:02 字數 1567 閱讀 7114

題意:問連續重複部分最多的串是什麼,不能重疊,且我們要字典序最小的串如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...