POJ 3693 字尾陣列 RMQ

2022-04-07 11:40:32 字數 1441 閱讀 3810

點選開啟鏈結

題意:問連續重複部分最多的串是什麼,不能重疊,且我們要字典序最小的串如xbcabcab,有bcabca重複次數為2,cabcab重複次數也為2,那麼要前邊那個

思路:以前寫過乙個類似的,spoj 687,這個只是求連續重複部分最多的串的次數,並不需要將按字典序最小串輸出,那麼我們可以用到spoj687的**,用它我們可以求出那個重複的次數和滿足這個次數的串的長度,那麼就只差找到字典序最小的那個串了,而我們知道字尾陣列的sa陣列就是按字典序來的嘛,從字典序最小開始找,找到就跳出,輸出即可,如何判斷以sa[i]開始的滿不滿足呢,因為我們有了可以達到重複次數的長度,那麼列舉這個長度,在計算一次個數,與重複次數相同就滿足條件了,看**好理解

#include

#include

#include

#include

#include

using namespace std;

typedef long long ll;

const int inf=0x3f3f3f3f;

const int maxn=100010;

int wa[maxn],wb[maxn],wv[maxn],ww[maxn];

int sa[maxn],lcp[maxn],rank[maxn],rank1[maxn],dp[maxn][20];

char str[maxn];

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<=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=slove(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 字尾陣列 RMQ

這道題是字尾陣列的乙個典型應用。求乙個串中連續重複次數最多的乙個子串。做這道題的時候要把握住,連續重複 和 次數最多這兩個關鍵,才能有突破。下面的思路是照搬大牛的 大神不要打我 在字尾陣列神文中有這題的題解。比較容易理解的部分就是列舉長度為l,然後看長度為l的字串最多連續出現幾次。既然長度為l的串重...

poj3693 字尾陣列 RMQ

感覺思路還是非常神奇的。另外注意一下strlen好像是個on的函式。日狗。tle了乙個晚上。include include include includeusing namespace std define maxn 100005 define forup i,a,b for int i a i b...

字尾陣列 poj 3693

題目 給出乙個串,求重複次數最多的連續重複子串 列舉長度為l,然後看長度為l的字串最多連續出現幾次。既然長度為l的串重複出現,那麼str 0 str l str 2 l 中肯定有兩個連續的出現在字串中。那麼就列舉連續的兩個,然後從這兩個字元前後匹配,看最多能匹配多遠。即以str i l str i ...