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