关于莫队,树状数组,离散化
上次学了主席树之后,很快就忘记了是怎么一回事了,所以这次学习莫队,我决定记个笔记。如果有人看到,却未能看懂,那真是抱歉了,当然如果大家想了解的话可以留言,我会试着出一期博客来讲述一下算法的大致框架。
//不过今天是真的很晚了,就全当是个人总结式了
在这里插入图片描述
莫队: 通过移动两边端点的方式来完成访问,所以要对询问进行排序,奇偶反序(减少波峰),按照’根号(n)'进行分块。在询问的时候进行增减,复杂度o(n**1.5)。
树状数组:通过lowbit(x)的关系,log(n)的返回某一段数组的和。比线性快很多。
具体代码:
int lowbit(int x){
return x&(-x);
}
int q(int x){
int res(0);
for( ; x >= 0; res += c[x],x -= lowbit(x));
return res;
}
void u(int x,int v){
for( ;x < n; c[x] +=v,x += lowbit(x));
return;
}
lowbit函数的实现方法与负数是正数的补码有关,自己理解一下,返回的是2^k(k为x最低位起的连续0的最长度)
最后是离散化:
unique进行删重
int size=unique(a,a+n)-a;
!!!!!size则是删重后的数组长度 !!!!!
low_bound(a,a+size,query[i])
!!!!!可以快速返回该值是区间中的第几大!!!!!
特别提到2019年 (今年的) jscpc中的c题,需要离散化a[i]以及他加k减k的数,然后通过莫队的询问,树状数组的修改莫队询问值状态,可得到树状数组区间内符合条件数个数(询问a[i]+k减询问a[i]-k)也就是询问结果,删除数的话同样删掉区间询问的结果,大概就是这样吧。说真的,博主当时是真的一点都不会,所以看了题解感觉大概思路是这样的,如果不对,还请指出。
今天写博客的时间非常晚,有待完善,还请多多指教。