傳送門 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,含義如題 接下來一...