写在前面:
分块的思想让我们对一个区间操作编的简单,这是因为,我们在一开始(读取数据的时候)就对一部分区间(块)进行了操作。
- 肯定要有块的大小(一个块里的data个数) 建议是 sqrt(n);
- 把块存在一个数组中,我们把第几个块成为块的下标,所以我们知道最后一个块的下标是 : n / sqrt(n); (这里要注意 块的下标一定是从0开始存的!!!为什么呢 因为我们可以快速根据 data的下标找到data所在块的下标 data下标/块的大小)
- 但是我们的data的下标可以从0 开始存也可以从1开始存,不会对我们的分块的操作有影响!!!!因为不管从 0 还是1 开始存,只会影响第一个块里的data的多少
- 为了叙述方便
我们把块的下标叫做块的id - 敲黑板了!!!
- id为n的块对应data的区间(下标)为
[id*size , (id+1)*size -1]
关于块的操作:
我们要求 从 L 到 R 的区间 操作:
如果 L的对应块(L/size) 和R的对应块(R/size)一样那就只能暴力了,说明L 到R 在一个块中
要是不一样 我们要分三段
从 L 到 L 对应块的末尾
从 L 的下一块到 R 对应块的上一个块
从 R 对应块的开始到 R
- 这个例子是求 从L 到 R 的区间和
- 块的内容是对应data的下标的区间 在读取数据的时候已经搞定
int quarry(int l,int r){
int idl=l/size;
int idr=r/size;
int ans=0;
if(l==r){
for(int a=l;a<=r;a++){
ans+=data[a];
}
return ans;
}else{
for(int th=l;th<(idl+1)*size;th++){
ans+=data[th];
}
for(int id=idl;id<idr;id++){
ans+=kuai[id];
}
for(int th=idr*size;th<=r;th++){
ans+=data[th];
}
return ans;
}
}
- 一定要自己写代码