傳送門
字尾平衡樹模板題
用平衡樹維護每乙個字尾的排名
關鍵在於查詢兩個字尾的大小
可以用二分加hash,複雜度 \(log^2n\) 插入
或者:每次前面插入乙個字元,先比較兩個字尾第乙個字元的大小
而後面的大小我們已經在平衡樹上維護好了
像這樣分配權值
給樹上每個子樹乙個實數權值區間 \([l,r]\),這個點權值為 \(mid=\frac\)那麼可以做到 \(o(1)\) 比較左子樹 \([l,mid]\) 右子樹 \([mid,r]\)
只需要選擇乙個樹高 \(log\) 的樹(treap/替罪羊樹)使得滿足精度要求即可
最後用線段樹維護一下每個幻影的最小的字尾
# include using namespace std;
typedef long long ll;
const int maxn(1e6 + 5);
const double alpha(0.75);
int ls[maxn], rs[maxn], rt, tot, size[maxn], que[maxn], cnt;
double val[maxn];
int mn[maxn << 1], id[maxn], n, m, p[maxn], pos[maxn];
char s[maxn];
void dfs(int u)
int build(int l, int r, double vl, double vr)
int rebuild(int x, double vl, double vr)
inline int compare(int x, int y)
int insert(int &x, double vl, double vr, int ps)
if (alpha * size[x] < max(size[ls[x]], size[rs[x]])) x = rebuild(x, vl, vr);
if (compare(ps, pos[x])) ret = insert(ls[x], vl, midv, ps);
else ret = insert(rs[x], midv, vr, ps);
size[x] = size[ls[x]] + size[rs[x]] + 1;
return ret;
}void modify(int x, int l, int r, int ps)
}int query(int x, int l, int r, int ql, int qr)
return ret;
}int main()
else if (op == 'c')
else scanf("%d%d", &l, &r), printf("%d\n", ans = query(1, 1, n, l, r));
} return 0;
}
BZOJ3682 Phorni 字尾平衡樹
傳送門 字尾平衡樹模板題 用平衡樹維護每乙個字尾的排名 關鍵在於查詢兩個字尾的大小 可以用二分加hash,複雜度 log 2n log 2n log2 n 插入 或者 每次前面插入乙個字元,先比較兩個字尾第乙個字元的大小 而後面的大小我們已經在平衡樹上維護好了 像這樣分配權值 給樹上每個子樹乙個實數...
bzoj 1692 字尾陣列
將乙個字串進行如下操作 每次拿去首或尾,放在新字串尾,問新字串字典序最小的情況。直覺貪心,但情況複雜。可以用字尾陣列,每次比較當前剩餘串正序和倒序哪種字典序小,可以如下構建 abcd abcd0dcba include include include include include include ...
bzoj 2119 字尾陣列
題意 給乙個串,求形如aba,其中b的長度為m,a的長度不限的子串的數量。求正串反串的字尾陣列和對於h的rmq。列舉a串長度len,對於每個長度為len的區間處理在這段區間開始的子串個數。每隔len列舉i,然後用rmq求i和i len m的最長公共字首字尾l,r。統計長度為len的在區間 i l 1...