傳送門
字尾平衡樹模板題
用平衡樹維護每乙個字尾的排名
關鍵在於查詢兩個字尾的大小
可以用二分加hash,複雜度 log
2n
log^2n
log2
n 插入
或者:每次前面插入乙個字元,先比較兩個字尾第乙個字元的大小
而後面的大小我們已經在平衡樹上維護好了
像這樣分配權值
給樹上每個子樹乙個實數權值區間 [l,那麼可以做到 o(1r]
[l,r]
[l,r
],這個點權值為 mid
=l+r
2mid=\frac
mid=2l
+r左子樹 [l,
mid]
[l,mid]
[l,mid
] 右子樹 [mi
d,r]
[mid,r]
[mid,r
]
)o(1)
o(1)
比較只需要選擇乙個樹高 log
loglo
g 的樹(treap/替罪羊樹)使得滿足精度要求即可
最後用線段樹維護一下每個幻影的最小的字尾
# include
using
namespace std;
typedef
long
long ll;
const
intmaxn
(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)
intbuild
(int l,
int r,
double vl,
double vr)
intrebuild
(int x,
double vl,
double vr)
inline
intcompare
(int x,
int y)
intinsert
(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));
}return0;
}
BZOJ3682 Phorni 字尾平衡樹
傳送門 字尾平衡樹模板題 用平衡樹維護每乙個字尾的排名 關鍵在於查詢兩個字尾的大小 可以用二分加hash,複雜度 log 2n 插入 或者 每次前面插入乙個字元,先比較兩個字尾第乙個字元的大小 而後面的大小我們已經在平衡樹上維護好了 像這樣分配權值 給樹上每個子樹乙個實數權值區間 l,r 這個點權值...
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...