【玄学】vector实现伪平衡树和玄学带修改莫队
(由于某些原因,这篇老文章发的时候有一点too naive了,所以orz,错误连篇,可以忽略观看
玄学之道orz
我们总有要用到平衡树的时候吧,如果时间较充裕,完全各种神奇平衡树可以往上套,但即使用再简短的平衡树(例如FHQ树),也有快到考试结束没时间的时候,这时候紧急需要一个平衡树救场却写爆,写错就尬了。这时候玄学vector就出现了。
模板(LOJ普通平衡树):
update(2018/10/8)发现vector使用分块存储技术,因此插入删除都是logn的,万岁!
操作1:插入,O(log n)
操作2:删除,O(log n)(但vector的插入删除不知为何就是比普通数组快orz)
操作3: 查询排名 ,O(log n )
操作4:查询排名对应数字,O(1)
操作5:前驱,O(log n)
操作6:后继,O(log n)
修改同理,O(n)
看上去时间复杂度有些爆炸,,但实际情况由于常数很小,只有不是疯狂插入删除的情况还是可以比较好的面对的。这个东西同样可以面对二逼平衡树(树套树,序列区间平衡树查询),这时候直接套一个树状数组就可以了。
#include当然该写平衡树还是写平衡树啊,,不要被卡傻了来找我(orz 不想新开文章,顺便写一波玄学--带修改莫队 普通莫队时间复杂度很好证,以L分块,R排序。时间n sqrt(n),当然因为玄学,块长取n^(2/3)比较优秀 带修改莫队:以L分块,L块同以R分块,最后还同以t排序。此时分块大小为根号3下(nt)可以达到最好时间复杂度 根号3下(n^4t)。 证明?不会,自己看着办吧orz#include #include #include using namespace std; vector ve; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { int opt,x; scanf("%d%d",&opt,&x); if(opt==1) ve.insert(lower_bound(ve.begin(),ve.end(),x),x); else if(opt==2) ve.erase(lower_bound(ve.begin(),ve.end(),x)); else if(opt==3) printf("%d\n",lower_bound(ve.begin(),ve.end(),x)-ve.begin()+1); else if(opt==4) printf("%d\n",ve[x-1]); else if(opt==5) printf("%d\n",*--lower_bound(ve.begin(),ve.end(),x)); else if(opt==6) printf("%d\n",*upper_bound(ve.begin(),ve.end(),x)); } }