BZOJ4310 跳蚤(字尾陣列 二分答案)

2022-05-20 16:01:39 字數 1139 閱讀 7859

注意到答案一定是原串的子串,於是考慮造出sa,二分答案是第幾小的子串。第k小子串很容易在sa上求出。之後計算使他成為最大子串至少要在幾個位置切割,對每個字典序比答案大的字尾,找到所有合法切割位置(求lcp即可),就轉化成了選最少的點使每個區間都包含至少乙個點的經典問題。

#include#include

#include

#include

#include

#include

using

namespace

std;

intread()

while (c>='

0'&&c<='

9') x=(x<<1)+(x<<3)+(c^48),c=getchar();

return x*f;

}#define n 100010

#define ll long long

int n,m,sa[n],sa2[n],rk[n<<1],tmp[n<<1

],h[n],cnt[n],l[n];

char

s[n];

ll tot=0

;void

make()

if (p==n) break

; m=p;

}for (int i=1;i<=n;i++)

}bool

check(ll k)

else k-=n-sa[i]+1-h[sa[i]];

k+=h[sa[x]];memset(l,0,sizeof

(l));

int lcp=k;if (k1) l[sa[x]+lcp-1]=max(l[sa[x]+lcp-1

],sa[x]);

for (int i=x+1;i<=n;i++)

int t=1

;

for (int i=1;i<=n;i++)

if(l[i])

return1;

}int

main()

for (int i=1;i<=n;i++)

if (ans<=n-sa[i]+1-h[sa[i]])

else ans-=n-sa[i]+1-h[sa[i]];

return0;

}

BZOJ4310 跳蚤 字尾陣列 二分

很久很久以前,森林裡住著一群跳蚤。一天,跳蚤國王得到了乙個神秘的字串,它想進行研究。首先,他會把串 分成不超過 k 個子串,然後對於每個子串 s,他會從s的所有子串中選擇字典序最大的那乙個,並在選出來的k個子串中選擇字典序最大的那乙個。他稱其為 魔力串 現在他想找乙個最優的分法讓 魔力串 字典序最小...

BZOJ4310 跳蚤(字尾陣列 二分答案)

傳送門 dar kbzo jdarkbzoj darkbz oj上題面有誤,應該是最大的最小 考慮二分這個最小的串x xx的排名k kk那麼也就是說所有排名比這個大的一定要被切開 考慮乙個字尾s p n s p,n s p,n 如果l cp s p n x 0 lcp s p,n x 0 lcp s...

BZOJ4310 跳蚤 字尾陣列 ST表 二分

趕緊寫完,就能快點回去洗澡了 bzoj4310傳送門 給乙個長度不超過100000的字串。現在要把這個字串分成k組 k不超過length 然後對於每一組,取其字典序最大的子串,得到乙個集合s,記s中字典序最大的那個串為ss,詢問ss字典序最小可以是什麼 輸入格式 第一行乙個整數k,含義如題 接下來一...