2022.11.09
草,神圣的数组 \(a\) 爆草平衡树板子
P5239
先 \(n^2\) 预处理出 \(1000\) 内的 C,再焯一个二维前缀和就完事了。
P1688
大家好,我喜欢 Hash,所以我用 Hash 通过了这道题。
看这儿
P1081
倍增毒瘤题,要不是这篇帖子我就死在机房了。
因为我写的实在太好了:
shit mountain
void init(){
for(int i = 2; i <= n; ++i)lg[i] = lg[i >> 1] + 1;
s.insert({0, -inf + 1}), s.insert({0, -inf});
s.insert({0, inf}), s.insert({0, inf - 1});
for(int i = n; i; --i){
Node l1, l2, r1, r2;
int ja, jb;
s.insert(a[i]);
auto it = s.lower_bound(a[i]);
it--, it--;
l2 = *it;it++;l1 = *it;
it++, it++;
r1 = *it;it++;r2 = *it;
if(Abs(l1.h - a[i].h) < Abs(r1.h - a[i].h)){
jb = l1.id;
if(Abs(r1.h - a[i].h) < Abs(l2.h - a[i].h))
ja = r1.id;
else if(Abs(r1.h - a[i].h) == Abs(l2.h - a[i].h))
ja = r1.h < l2.h ? r1.id : l2.id;
else
ja = l2.id;
}else if(Abs(l1.h - a[i].h) == Abs(r1.h - a[i].h)){
jb = l1.h > r1.h ? r1.id : l1.id;
ja = l1.h < r1.h ? r1.id : l1.id;
}else{
jb = r1.id;
if(Abs(r2.h - a[i].h) < Abs(l1.h - a[i].h))
ja = r2.id;
else if(Abs(r2.h - a[i].h) == Abs(l1.h - a[i].h))
ja = r2.h < l1.h ? r2.id : l1.id;
else
ja = l1.id;
}
f[i][0][0] = ja;
f[i][0][1] = jb;
fa[i][0][0] = Abs(a[ja].h - a[i].h);
fb[i][0][1] = Abs(a[jb].h - a[i].h);
}
for(int i = 1; i <= n; ++i){
f[i][1][0] = f[f[i][0][0]][0][1];
f[i][1][1] = f[f[i][0][1]][0][0];
fa[i][1][0] = fa[i][0][0];
fa[i][1][1] = fa[f[i][0][1]][0][0];
fb[i][1][1] = fb[i][0][1];
fb[i][1][0] = fb[f[i][0][0]][0][1];
}
for(int i = 2; i <= lg[n]; ++i){
for(int j = 1; j <= n; ++j){
f[j][i][0] = f[f[j][i - 1][0]][i - 1][0];
f[j][i][1] = f[f[j][i - 1][1]][i - 1][1];
fa[j][i][0] = fa[j][i - 1][0] + fa[f[j][i - 1][0]][i - 1][0];
fa[j][i][1] = fa[j][i - 1][1] + fa[f[j][i - 1][1]][i - 1][1];
fb[j][i][0] = fb[j][i - 1][0] + fb[f[j][i - 1][0]][i - 1][0];
fb[j][i][1] = fb[j][i - 1][1] + fb[f[j][i - 1][1]][i - 1][1];
}
}
return ;
}
调这玩意眼睛会先瞎掉,然后把头搞秃掉,然后原地去世。
但这题毒瘤归毒瘤,它的确是道倍增的好题。这道题要用倍增把暴力优化成
\(\text{nlogn}\) 级别,这让倍增的作用极好地体现出来了。