字尾陣列
字尾陣列 (sa) 是一種重要的資料結構,通常使用倍增或者dc3演算法實現,這超出了我們的討論範圍。
在本題中,我們希望使用快排、hash與二分實現乙個簡單的o(nlog2n)的字尾陣列求法。
詳細地說,給定乙個長度為 n 的字串s(下標 0~n-1),我們可以用整數 k(0≤k輸入格式
輸入乙個字串,其長度不超過30萬。
字串由小寫字母構成。
輸出格式
第一行為陣列sa,相鄰兩個整數用1個空格隔開。
第二行為陣列height,相鄰兩個整數用1個空格隔開,我們規定height[1]=0。
輸入樣例:
ponoiiipoi
輸出樣例:
9 4 5 6 2 8 3 1 7 0
0 1 2 1 0 0 2 1 0 2
說實話看到這道題的時候真的是一臉懵,這東西咋用hash,二分,快排。
後來找了些部落格看,終於理解其中的思路了,
一、先記錄整條的hash值。
二、用乙個sort函式,自定義cmp。
三、通過二分確定兩個字尾字元之間的字首相同字母。
這道題寫這篇題解的時候又重新去寫了一遍,感覺真的難。
#include
#include
#include
#include
using
namespace std;
typedef
unsigned
long
long ull;
const
int base =
131;
const
int n =
3e5+10;
char str[n]
;ull h[n]
, p[n]
;int sa[n]
, n;
ull gethash
(int l,
int r)
intsumsub
(int a,
int b)
return r;
}bool
cmp(
int a,
int b)
intmain()
sort
(sa +
1, sa + n +
1, cmp)
;//對下標進行排序。
for(
int i =
1; i <= n; i++
)printf
("%d%c"
, sa[i]-1
, i == n ?
'\n'
:' ');
printf
("0 ");
for(
int i =
2; i <= n; i++
)printf
("%d%c"
,sumsub
(sa[i]
, sa[i -1]
), i == n ?
'\n'
:' ');
return0;
}
這個演算法耗時還是非常長的,並不是真正的能用的演算法,但是這個寫法的綜合力度還是比較高的,思想還是可以借鑑的。 《演算法競賽高階指南》 防曬
有c頭奶牛進行日光浴,第i頭奶牛需要minspf i 到maxspf i 單位強度之間的陽光。每頭奶牛在日光浴前必須塗防曬霜,防曬霜有l種,塗上第i種之後,身體接收到的陽光強度就會穩定為spf i 第i種防曬霜有cover i 瓶。求最多可以滿足多少頭奶牛進行日光浴。輸入格式 第一行輸入整數c和l。...
《演算法競賽高階指南》蚯蚓
蛐蛐國最近蚯蚓成災了!隔壁跳蚤國的跳蚤也拿蚯蚓們沒辦法,蛐蛐國王只好去請神刀手來幫他們消滅蚯蚓。蛐蛐國裡現在共有 n 只蚯蚓,第 i 只蚯蚓的長度為 ai 所有蚯蚓的長度都是非負整數,即可能存在長度為0的蚯蚓。每一秒,神刀手會在所有的蚯蚓中,準確地找到最長的那乙隻,將其切成兩段。若有多隻最長的,則任...
演算法競賽高階指南筆記
原碼 原碼就是符號位加上真值的絕對值,即用第一位表示符號,其餘位表示值.比如如果是8位二進位制 其中,第一位為1是負數 1 0000 0001 原 1 1000 0001 原 因此,8位二進位制數的取值範圍 127,127 補碼正數的補碼是其本身 負數的補碼是在其原碼的基礎上,符號位不變,其餘各位取...