這是一道模板題。
讀入乙個長度為 \(n\) 的由大小寫英文本母或數字組成的字串,請把這個字串的所有非空字尾按字典序從小到大排序,然後按順序輸出字尾的第乙個字元在原串中的位置。位置編號為 \(1\) 到 \(n\) 。
輸入格式:
一行乙個長度為 \(n\) 的僅包含大小寫英文本母或數字的字串。
輸出格式:
一行,共 \(n\) 個整數,表示答案。
輸入樣例#1:複製
ababa
輸出樣例#1:複製
5 3 1 4 2
\(n <= 10^6\)
num[i]=桶計數
sa[i]=第i個排名的字尾的開頭位置
先來看個圖
接下來看**
void sort()
這時候比較難理解的就是最後一句對吧,別急,看後面的**。
cnt=0;
for(int i=1;i<=w;i++)tp[++cnt]=n-w+i;
for(int i=1;i<=n;i++)if(sa[i]>w)tp[++cnt]=sa[i]-w;
#include#include#include#include#includeusing namespace std;
const int n=1000100;
char s[n];
int sa[n],rak[n],tp[n],num[n];
int n,m=200;
void sort()
void sa_sort()
sort();
int p=0,w=1,cnt;
while(pw)tp[++cnt]=sa[i]-w;
sort();swap(rak,tp);
rak[sa[1]]=p=1;
for(int i=2;i<=n;i++)
if((tp[sa[i]]==tp[sa[i-1]])&&(tp[sa[i]+w]==tp[sa[i-1]+w]))
rak[sa[i]]=p;
else rak[sa[i]]=++p;
w<<=1;m=p;
}}int main()
return 0;
}
P3809 模板 字尾排序 (字尾陣列sa )
題意 讀入乙個長度為 n的由大小寫英文本母或數字組成的字串,請把這個字串的所有非空字尾按字典序從小到大排序,然後按順序輸出字尾的第乙個字元在原串中的位置。位置編號為 1到 n。資料範圍 n 1e6 解法 題目要求的是排名第x的字尾在原串中的位置,其實就是字尾陣列中的sa陣列,算出來直接輸出就行了 c...
SA 字尾陣列
首先一定要確定sa 是個什麼東西 sa i 表示的是排名為 i 的字尾是哪乙個 至於字尾 i的排名是多少,那個是ra nk i 當然啦 最最最難懂的就是基數排序 要是不用基數排序,每次對於乙個二元組直接so rt一下 這樣的複雜度是o nlog 2 對於二元組的基數排序應該是這樣做的 首先把所有元素...
字尾陣列SA
給定乙個字串s,按字典序排序s的所有子串 鬼知道什麼思想,好像沒有什麼思想。哦,想起來了,是倍增。考慮最簡單的字尾間o n o n 比較和快排o nlog n o n logn 總複雜度o n2lo gn o n 2log n 考慮優化字串間的比較,用倍增的思想,假設k 2 k 2 長度的已經比完了...