一道字串練習題

2021-10-02 00:10:45 字數 2061 閱讀 8474

給了乙個長度為n的字串,要求將其分為k段,求這k段最長的並且字典序最小的lcs.

k ≤n

≤1e5

,∣∑∣

小寫字母

k\le n\le 1e5,|\sum|小寫字母

k≤n≤1e

5,∣∑

∣小寫字

母二分+hash+sa

首先可以把問題轉化為求乙個最長的並且字典序最小的字串,在原串中不重疊地出現了k次.

然後二分這個字串的長度l,因為原串長度為l的字串數量是o(n

)o(n)

o(n)

級別的,所以可以把每個字串的hash值算出來,分成幾種字串,對每種字串計算不重疊出現次數最多是多少,然後判斷兩個字串的字典序需要預處理出sa,然後直接o(1

)o(1)

o(1)

比較兩個字串的開頭所在的字尾大小就可以了.

#include

using

namespace std;

const

int maxn=

1e5+5;

typedef

unsigned

long

long ull;

const ull step=

23,mod=

4115188075855873ll

;//2^57+1再移除前兩位,比較大的模數可以減少hash衝突,畢竟這題不能掛鏈

inline

intread()

while

(isdigit

(c))

return t*f;

}int n,k;

int x[maxn]

,y[maxn]

,sa[maxn]

,rk[maxn]

,m=300

,t[maxn]

;char s[maxn]

;void

get(

)swap

(x,y)

;x[sa[1]

]=1;num=1;

for(

int i=

2;i<=n;i++

) x[sa[i]]=

(y[sa[i]

]==y[sa[i-1]

])&&(y[sa[i]

+k]==y[sa[i-1]

+k])

?num:

++num;

if(num==n)

break

; m=num;

}for

(int i=

1;i<=n;i++

)rk[sa[i]

]=i;

}ull ha[maxn]

;int ans;

char alfa[maxn]

;typedef pairint> pii;

pii mp[maxn]

;bool

calc

(int x)

for(

int i=x+

1;i<=n;i++

)int len=n-x+1;

for(

int i=

1;i<=n-x+

1;i++

)sort

(mp+

1,mp+

1+len)

;int lst=

1,bt=

0,flag=0;

for(

int i=

1;i<=len;i++)if

(cnt>=k)}}

} lst=i+1;

}}if(flag&&x>ans)

for(

int i=bt;i)alfa[i-bt]

=s[i]

;return flag;

}int

main()

else r=mid-1;

}if(ans)

else

puts

("kyoma is wrong.");

return0;

}

一道字串練習題

求乙個字串有多少本質不同的子串,這裡的不同指兩個子串的最小表示法不同.n 5 e4,1 a i n 其中n 是字串 長度,a i 是 字元 n 5e4,1 a i n,其中n是字串長度,a i 是字元 n 5 e4,1 a i n 其中n 是字串 長度,a i 是 字元首先,如果不同指字串本身不同,...

一道互動練習題

的做法 考慮逐位確定 對於每個位置,往後列舉有沒有位置可以使得正確位置更多,如果有,那麼有兩種情況,1是這個位置被放到了正確的位置,2是這個位置本來應該放的數被放來了 這裡的重點是我們需要區分1和2 具體的做法是記下讓這個位置答案正確位置數變大的2個位置,將其和i一起移位 這裡是手繪示意圖.即把p1...

一道fft練習題

考場上想到的o n 2 o n 2 o n2 暴力 記f i j f i j f i j 表示前i個位置,長度為j的連擊出現的期望次數 記g i j g i j g i j 表示第到i個位置為止,目前連擊次數為j的概率 轉移時有一些細節 include using namespace std con...