平方分割(WIP)
(data_structure/sqrtd.hpp)
Code
/**
* @brief 平方分割(WIP)
*/
template<typename T>
struct sqrtd{
vector<T>v;
int n,b,geta;
sqrtd(vector<T>v):v(v),n(v.size()),b(sqrt(n)),geta(n),val(v),bukket((n+b)/b),sum((n+b)/b),cnt((n+b)/b),cnt2((n+b)/b,vector<int>(2*n)){
for(int i=0;i<n;i++){
cnt2[i/b][v[i]+geta]++;
if(v[i]<0)continue;
sum[i/b]+=v[i];
cnt[i/b]++;
}
}
vector<T>val;
vector<T>bukket,sum,cnt;
vector<vector<int>>cnt2;
void add(int l,int r){
if(l/b==r/b){
for(int i=l;i<r;i++){
cnt2[i/b][val[i]+geta]--;
val[i]++;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>0)sum[i/b]++;
if(val[i]+bukket[i/b]==0)cnt[i/b]++;
}
return;
}
for(int i=l;i<l/b*b+b;i++){
cnt2[i/b][val[i]+geta]--;
val[i]++;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>0)sum[i/b]++;
if(val[i]+bukket[i/b]==0)cnt[i/b]++;
}
for(int i=l/b+1;i<r/b;i++){
bukket[i]++;
sum[i]+=cnt[i];
cnt[i]+=cnt2[i][-bukket[i]+geta];
}
for(int i=r/b*b;i<r;i++){
cnt2[i/b][val[i]+geta]--;
val[i]++;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>0)sum[i/b]++;
if(val[i]+bukket[i/b]==0)cnt[i/b]++;
}
}
void sub(int l,int r){
if(l/b==r/b){
for(int i=l;i<r;i++){
cnt2[i/b][val[i]+geta]--;
val[i]--;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>-1)sum[i/b]--;
if(val[i]+bukket[i/b]==-1)cnt[i/b]--;
}
return;
}
for(int i=l;i<l/b*b+b;i++){
cnt2[i/b][val[i]+geta]--;
val[i]--;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>-1)sum[i/b]--;
if(val[i]+bukket[i/b]==-1)cnt[i/b]--;
}
for(int i=l/b+1;i<r/b;i++){
cnt[i]-=cnt2[i][-bukket[i]+geta];
bukket[i]--;
sum[i]-=cnt[i];
}
for(int i=r/b*b;i<r;i++){
cnt2[i/b][val[i]+geta]--;
val[i]--;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>-1)sum[i/b]--;
if(val[i]+bukket[i/b]==-1)cnt[i/b]--;
}
}
T query(int l,int r){
T res=T();
if(l/b==r/b){
for(int i=l;i<r;i++){
if(val[i]+bukket[i/b]>0)res+=val[i]+bukket[i/b];
}
return res;
}
for(int i=l;i<l/b*b+b;i++){
if(val[i]+bukket[i/b]>0)res+=val[i]+bukket[i/b];
}
for(int i=l/b+1;i<r/b;i++){
res+=sum[i];
}
for(int i=r/b*b;i<r;i++){
if(val[i]+bukket[i/b]>0)res+=val[i]+bukket[i/b];
}
return res;
}
};
#line 1 "data_structure/sqrtd.hpp"
/**
* @brief 平方分割(WIP)
*/
template<typename T>
struct sqrtd{
vector<T>v;
int n,b,geta;
sqrtd(vector<T>v):v(v),n(v.size()),b(sqrt(n)),geta(n),val(v),bukket((n+b)/b),sum((n+b)/b),cnt((n+b)/b),cnt2((n+b)/b,vector<int>(2*n)){
for(int i=0;i<n;i++){
cnt2[i/b][v[i]+geta]++;
if(v[i]<0)continue;
sum[i/b]+=v[i];
cnt[i/b]++;
}
}
vector<T>val;
vector<T>bukket,sum,cnt;
vector<vector<int>>cnt2;
void add(int l,int r){
if(l/b==r/b){
for(int i=l;i<r;i++){
cnt2[i/b][val[i]+geta]--;
val[i]++;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>0)sum[i/b]++;
if(val[i]+bukket[i/b]==0)cnt[i/b]++;
}
return;
}
for(int i=l;i<l/b*b+b;i++){
cnt2[i/b][val[i]+geta]--;
val[i]++;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>0)sum[i/b]++;
if(val[i]+bukket[i/b]==0)cnt[i/b]++;
}
for(int i=l/b+1;i<r/b;i++){
bukket[i]++;
sum[i]+=cnt[i];
cnt[i]+=cnt2[i][-bukket[i]+geta];
}
for(int i=r/b*b;i<r;i++){
cnt2[i/b][val[i]+geta]--;
val[i]++;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>0)sum[i/b]++;
if(val[i]+bukket[i/b]==0)cnt[i/b]++;
}
}
void sub(int l,int r){
if(l/b==r/b){
for(int i=l;i<r;i++){
cnt2[i/b][val[i]+geta]--;
val[i]--;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>-1)sum[i/b]--;
if(val[i]+bukket[i/b]==-1)cnt[i/b]--;
}
return;
}
for(int i=l;i<l/b*b+b;i++){
cnt2[i/b][val[i]+geta]--;
val[i]--;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>-1)sum[i/b]--;
if(val[i]+bukket[i/b]==-1)cnt[i/b]--;
}
for(int i=l/b+1;i<r/b;i++){
cnt[i]-=cnt2[i][-bukket[i]+geta];
bukket[i]--;
sum[i]-=cnt[i];
}
for(int i=r/b*b;i<r;i++){
cnt2[i/b][val[i]+geta]--;
val[i]--;
cnt2[i/b][val[i]+geta]++;
if(val[i]+bukket[i/b]>-1)sum[i/b]--;
if(val[i]+bukket[i/b]==-1)cnt[i/b]--;
}
}
T query(int l,int r){
T res=T();
if(l/b==r/b){
for(int i=l;i<r;i++){
if(val[i]+bukket[i/b]>0)res+=val[i]+bukket[i/b];
}
return res;
}
for(int i=l;i<l/b*b+b;i++){
if(val[i]+bukket[i/b]>0)res+=val[i]+bukket[i/b];
}
for(int i=l/b+1;i<r/b;i++){
res+=sum[i];
}
for(int i=r/b*b;i<r;i++){
if(val[i]+bukket[i/b]>0)res+=val[i]+bukket[i/b];
}
return res;
}
};
Back to top page