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

2021-09-27 11:16:07 字數 2068 閱讀 7581

傳送門 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[

p,n]

,x)=

0那麼顯然不合法

否則考慮在lcp

lcplc

p前切開

考慮從後往前考慮每個字尾

那麼顯然每次在p+1

p+1p+

1切開一定就是最優的

#include

using

namespace std;

const

int rlen=

1<<20|

1;inline

chargc(

)#define gc getchar

inline

intread()

#define ll long long

#define re register

#define pii pair

#define pic pair

#define fi first

#define se second

#define pb push_back

#define cs const

#define bg begin

#define poly vector

#define chemx(a,b) ((a)<(b)?(a)=(b):0)

#define chemn(a,b) ((a)>(b)?(a)=(b):0)

cs int n=

100005

;namespace sa

inline

void

buildsa

(char

*a)for

(int i=

1,j,k=

0;i<=n;ht[rk[i++]]

=k)for

(k?k--:0

,j=sa[rk[i]-1

];s[j+k]

==s[i+k]

;k++);

}int lg[n]

,st[20]

[n<<1]

;inline

void

buildst()

inline

intlcp

(int x,

int y)

inline ll calc()

inline pii getkth

(ll k)

res+

=n-sa[i]+1

-ht[i];}

}inline

bool

comp

(int l1,

int r1,

int l2,

int r2)

inline

bool

check

(ll k,

int tim)

if(last>

1)tim--;if

(tim<0)

return

false

;return

true;}

inline

void

solve

(int k)

pii now=

getkth

(res)

;for

(int i=now.fi;i<=now.se;i++

)putchar

(s[i]

+'a'-1

);}}

int n,k;

char s[n]

;int

main()

BZOJ4310 跳蚤 字尾陣列 二分

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

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

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

BZOJ4310 跳蚤 字尾陣列 ST表 二分

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