字尾平衡樹

2022-01-31 23:18:07 字數 1150 閱讀 1667

如果需要動態維護字尾陣列,支援在字串前端插入乙個字元,詢問字尾的大小關係,如何做呢?

這是乙個不斷插入的問題,可以從增量的角度考慮。我們在前端插入乙個字元,其實就是插入了乙個新的字尾。我們的問題其實就是這個字尾排名多少。我們可以用平衡樹維護一下字尾陣列,從根節點開始二分比較這個字尾的大小,看看它應該被插到**。現在問題就變成了快速比較乙個新的字尾和乙個已有的字尾。

如果這個新的字尾和當前比較的字尾的首字元不同,那麼比較結果是顯然的;如果新的字尾和當前比較的字尾的首字元相同,那麼問題就轉化成了比較原來已有的兩個字尾的大小關係。我們在平衡樹的每個節點上維護乙個值\(x\in [0,1]\),代表它的大小,左兒子為的關鍵值為\([l,mid]\),右兒子的關鍵值為\([mid,r]\),那麼只要直接比較這個值就可以啦。

然而如果平衡樹的深度過大,那麼這個值會爆實數的精度。所以我們採用深度為\(o(logn)\)的平衡樹。但如果平衡樹需要旋轉,那麼它的子樹需要全部重新計算關鍵值。所以我們需要使用重量平衡樹,其子樹大小均攤\(o(logn)\),所以每次插入旋轉後整個子樹重算一下。

**:

#include#include#include#include#include#includeusing namespace std;

typedef long long giant;

int read()

const int maxn=3e5+1;

const int p=1e9+7;

char start[maxn];

int ans=0,len,type,ansh=0;

int convert(int x)

struct node

};struct sat

int newnode()

void revalue(int x,double lx,double rx)

bool rson(int x)

void getval(int x)

void rotate(int x)

bool compare(int x,int y)

int query(int x,int y) else if (op[0]=='q')

} printf("%d\n",ansh);

return 0;

}

字尾平衡樹學習筆記

給定乙個空串s 操作1 代表在 s前加入乙個字母使之成為新s 操作2 代表在詢問在當前 s中有多少連續子串等於給定串t 假設我們已經有了串 s的字尾平衡樹 插入乙個字母c 我們用s i代表原串 s 從第 i個字元開始的字尾 則字尾 cs 與 任意乙個字尾 si 的大小關係可以用 c與s i 的第乙個...

總結 字尾平衡樹學習筆記

字尾平衡樹,就是動態的維護字尾陣列,可以 o log n 在末尾插入字元,o log n 查詢 rank,sa 但是由於是維護的字尾資訊,所以插入只能在末尾插入字元 然後轉化成在開頭加乙個字元 相當於新增乙個字尾。方法一 我們需要一種能比較兩個字尾大小的方法,最簡單就是二分 hash,o log n...

BZOJ3682 Phorni 字尾平衡樹

傳送門 字尾平衡樹模板題 用平衡樹維護每乙個字尾的排名 關鍵在於查詢兩個字尾的大小 可以用二分加hash,複雜度 log 2n log 2n log2 n 插入 或者 每次前面插入乙個字元,先比較兩個字尾第乙個字元的大小 而後面的大小我們已經在平衡樹上維護好了 像這樣分配權值 給樹上每個子樹乙個實數...