data structures
存个板子,免得每次要用的时候不知道从哪题里拉(
bit
struct bit{
vector<int>tr;
int n;
void init(int N){n=N,tr=vector<int>(N+1,0);}
void add(int x,int y){for(;x<=n;x+=x&-x)tr[x]+=y;}
int ask(int x){
int s=0;
for(;x;x^=x&-x)s+=tr[x];
return s;
}
void down(){For(i,1,n)tr[i]+=tr[i^(i&-i)];}
}tr;
segment tree
template<class info,class oper>
struct segt{
int n;
vector<info>tr;
vector<oper>tag;
void init(vector<info>a){
n=a.size(); assert(n);
tr.assign(4<<__lg(n),info());
tag.assign(4<<__lg(n),oper());
function<void(int,int,int)>build=[&](int p,int l,int r){
if(l==r)return tr[p]=a[l],void();
int mid=l+r>>1;
build(p<<1,l,mid),build(p<<1|1,mid+1,r),up(p);
};
build(1,0,n-1);
}
void init(int _n){
n=_n; assert(n);
tr.assign(4<<__lg(n),info());
tag.assign(4<<__lg(n),oper());
}
void up(int p){
tr[p]=tr[p<<1]+tr[p<<1|1];
}
void pt(int p,oper v){
tr[p]+=v;
tag[p]+=v;
}
void down(int p){
pt(p<<1,tag[p]),pt(p<<1|1,tag[p]);
tag[p]=oper();
}
void upd(int p,int l,int r,int x,info y){
if(l==r)return tr[p]=y,void();
int mid=l+r>>1; down(p);
if(x<=mid)upd(p<<1,l,mid,x,y);
else upd(p<<1|1,mid+1,r,x,y); up(p);
}
void mdf(int p,int l,int r,int ql,int qr,oper v){
if(l>=ql&&r<=qr)return pt(p,v);
int mid=l+r>>1; down(p);
if(ql<=mid)mdf(p<<1,l,mid,ql,qr,v);
if(qr>mid)mdf(p<<1|1,mid+1,r,ql,qr,v); up(p);
}
info ask(int p,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr)return tr[p];
int mid=l+r>>1; down(p);
if(qr<=mid)return ask(p<<1,l,mid,ql,qr);
if(ql>mid)return ask(p<<1|1,mid+1,r,ql,qr);
return ask(p<<1,l,mid,ql,qr)+ask(p<<1|1,mid+1,r,ql,qr);
}
void upd(int x,info y){
--x;
upd(1,0,n-1,x,y);
}
void mdf(int l,int r,oper y){
if(l>r)return;
--l,--r;
mdf(1,0,n-1,l,r,y);
}
info ask(int l,int r){
if(l>r)return info();
--l,--r;
return ask(1,0,n-1,l,r);
}
template<class F>
int findL(int p,int l,int r,int ql,int qr,F &&f){
if(!F(tr[p]))return n+1;
if(l==r)return l;
int mid=l+r>>1,res=n+1; down(p);
if(ql<=mid)res=findL(p<<1,l,mid,ql,qr,f);
if(res==n+1 && qr>mid)res=findL(p<<1|1,mid+1,r,ql,qr,f);
return res;
}
template<class F>
int findR(int p,int l,int r,int ql,int qr,F &&f){
if(!F(tr[p]))return -1;
if(l==r)return l;
int mid=l+r>>1,res=-1; down(p);
if(qr>mid)res=findR(p<<1|1,mid+1,r,ql,qr,f);
if(res==-1 && ql<=mid)res=findR(p<<1,l,mid,ql,qr,f);
return res;
}
template<class F>
int findL(int l,int r,F &&f){
if(l>r)return -1;
--l,--r;
return findL(1,0,n-1,l,r,f)+1;
}
template<class F>
int findR(int l,int r,F &&f){
if(l>r)return -1;
--l,--r;
return findR(1,0,n-1,l,r,f)+1;
}
};
struct info{
info (){
}
};
struct oper{
oper (){
}
};
info operator +(info a,info b){
}
void operator +=(oper &a,oper b){
}
void operator +=(info &a,oper b){
}
\(O(1)-O(\sqrt N)\) 分块
struct DS{
ll s1[maxn],s2[1005];
int bel[maxn],L[1005],R[1005],B;
void init(int n){
B=sqrt(n);
For(i,1,n)bel[i]=(i-1)/B+1,s1[i]=0;
For(i,1,bel[n])L[i]=(i-1)*B+1,R[i]=min(n,i*B),s2[i]=0;
}
void add(int x,int y){s1[x]+=y,s2[bel[x]]+=y;}
ll ask(int x){
ll res=0;
For(i,L[bel[x]],x)res+=s1[i];
Rep(i,bel[x]-1,1)res+=s2[i];
return res;
}
}ds;
\(O(\sqrt N)-O(1)\) 分块
struct DS2{
ll s1[maxn],s2[1005];
int bel[maxn],L[1005],R[1005],B;
void init(int n){
B=sqrt(n);
For(i,1,n)bel[i]=(i-1)/B+1,s1[i]=0;
For(i,1,bel[n])L[i]=(i-1)*B+1,R[i]=min(n,i*B),s2[i]=0;
}
void add(int x,int y){
For(i,x,R[bel[x]])s2[i]+=y;
For(i,bel[x]+1,bel[n])s1[i]+=y;
}
ll ask(int x){return s1[x]+s2[bel[x]];}
}ds;
Grid
const int B1=22,B2=B1*B1,sN=500,ssN=24;
struct grid{
int s22[sN][sN],s23[sN][ssN],s32[ssN][sN],s33[ssN][ssN];
void add(int x2,int y2,int a){
int x3=x2/B1,y3=y2/B1;
s22[x2][y2]+=a;
s23[x2][y3]+=a;
s32[x3][y2]+=a;
s33[x3][y3]+=a;
}
int sum(int x2,int y2){
int s=0;
int x3=x2/B1,y3=y2/B1;
#define Fi3 For(i,0,x3-1)
#define Fi2 For(i,x3*B1,x2-1)
#define Fj3 For(j,0,y3-1)
#define Fj2 For(j,y3*B1,y2-1)
Fi3 Fj3 s+=s33[i][j];
Fi2 Fj2 s+=s22[i][j];
Fi2 Fj3 s+=s23[i][j];
Fi3 Fj2 s+=s32[i][j];
return s;
}
};
莫队/二离莫队
https://uoj.ac/submission/561663
1375H merge