分块
数列分块入门 1
比较简单的分块入门题,整块维护一个区间加的 \(tag\) ,散块长度肯定不超过 \(\sqrt n\) 直接暴力加,询问的时候加上区间 \(tag\) 即可。
#include<iostream>
#include<cmath>
#define away using
#define from namespace
#define OI std
#define Byrespect_lowsmile return 0
#define ll long long
away from OI;
const int N=5e4+5;
int bel[N],l[N],r[N];
ll a[N],tag[N];
int n,Bel;
inline int read()
{
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9')
{if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')
{s=s*10+ch-'0';ch=getchar();}
return s*w;
}
void build()
{
for(int i=1;i<=Bel;++i) l[i]=(i-1)*Bel+1,r[i]=i*Bel;
r[Bel]=n;
for(int i=1;i<=Bel;++i)
for(int j=l[i];j<=r[i];++j)
bel[j]=i;
return ;
}
void update(int x,int y,int v)
{
if(bel[x]==bel[y])
{
for(int i=x;i<=y;++i) a[i]+=v;
return ;
}
else
{
for(int i=x;i<=r[bel[x]];++i) a[i]+=v;
for(int i=l[bel[y]];i<=y;++i) a[i]+=v;
for(int i=bel[x]+1;i<=bel[y]-1;++i) tag[i]+=v;
return ;
}
}
ll query(int x)
{
return a[x]+tag[bel[x]];
}
int main()
{
n=read();
Bel=sqrt(n);
build();
for(int i=1;i<=n;++i) a[i]=read();
for(int i=1;i<=n;++i)
{
int op=read(),l=read(),r=read(),c=read();
if(op==0) update(l,r,c);
if(op==1) printf("%lld\n",query(r));
}
Byrespect_lowsmile;
}
数列分块入门 2
#include<iostream>
#include<algorithm>
#include<cmath>
#define away using
#define from namespace
#define OI std
#define Byrespect_lowsmile return 0
#define ll long long
away from OI;
const int N=5e4+5;
int a[N],l[N],r[N],bel[N],tag[N],sq[N];
int n,Bel;
inline int read()
{
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9')
{if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')
{s=s*10+ch-'0';ch=getchar();}
return s*w;
}
void build()
{
for(int i=1;i<=Bel;++i) l[i]=(i-1)*Bel+1,r[i]=i*Bel;
r[Bel]=n;
for(int i=1;i<=Bel;++i) sort(sq+l[i],sq+r[i]+1);
for(int i=1;i<=Bel;++i)
for(int j=l[i];j<=r[i];++j)
bel[j]=i;
return ;
}
void rebuild(int x)
{
for(int i=l[x];i<=r[x];++i) sq[i]=a[i];
sort(sq+l[x],sq+r[x]+1);
}
void update(int x,int y,int v)
{
if(bel[x]==bel[y])
{
for(int i=x;i<=y;++i) a[i]+=v;
rebuild(bel[x]);
return ;
}
else
{
for(int i=x;i<=r[bel[x]];++i) a[i]+=v;
rebuild(bel[x]);
for(int i=l[bel[y]];i<=y;++i) a[i]+=v;
rebuild(bel[y]);
for(int i=bel[x]+1;i<=bel[y]-1;++i) tag[i]+=v;
return ;
}
}
int query(int x,int y,int v)
{
int res=0;
if(bel[x]==bel[y])
{
for(int i=x;i<=y;++i)
if(a[i]+tag[bel[i]]<v*v) res++;
return res;
}
else
{
for(int i=x;i<=r[bel[x]];++i)
if(a[i]+tag[bel[i]]<v*v) res++;
for(int i=l[bel[y]];i<=y;++i)
if(a[i]+tag[bel[i]]<v*v) res++;
for(int i=bel[x]+1;i<=bel[y]-1;++i)
{
int pos=lower_bound(sq+l[i],sq+r[i]+1,v*v-tag[i])-sq;
res+=pos-l[i];
}
return res;
}
}
int main()
{
// freopen("fk.in","r",stdin);
// freopen("fk.out","w",stdout);
n=read();
Bel=sqrt(n);
for(int i=1;i<=n;++i) a[i]=read(),sq[i]=a[i];
build();
for(int i=1;i<=n;++i)
{
int op=read(),l=read(),r=read(),c=read();
if(op==0) update(l,r,c);
if(op==1) printf("%d\n",query(l,r,c));
}
Byrespect_lowsmile;
}
数列分块入门 3
#include<iostream>
#include<algorithm>
#include<cmath>
#define away using
#define from namespace
#define OI std
#define Byrespect_lowsmile return 0
#define ll long long
away from OI;
const int N=1e5+5;
int a[N],l[N],r[N],bel[N],tag[N],sq[N];
int n,Bel;
inline int read()
{
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9')
{if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')
{s=s*10+ch-'0';ch=getchar();}
return s*w;
}
void build()
{
for(int i=1;i<=Bel;++i) l[i]=(i-1)*Bel+1,r[i]=i*Bel;
r[Bel]=n;
for(int i=1;i<=Bel;++i) sort(sq+l[i],sq+r[i]+1);
for(int i=1;i<=Bel;++i)
for(int j=l[i];j<=r[i];++j)
bel[j]=i;
return ;
}
void rebuild(int x)
{
for(int i=l[x];i<=r[x];++i) sq[i]=a[i];
sort(sq+l[x],sq+r[x]+1);
}
void update(int x,int y,int v)
{
if(bel[x]==bel[y])
{
for(int i=x;i<=y;++i) a[i]+=v;
rebuild(bel[x]);
return ;
}
else
{
for(int i=x;i<=r[bel[x]];++i) a[i]+=v;
rebuild(bel[x]);
for(int i=l[bel[y]];i<=y;++i) a[i]+=v;
rebuild(bel[y]);
for(int i=bel[x]+1;i<=bel[y]-1;++i) tag[i]+=v;
return ;
}
}
int query(int x,int y,int v)
{
int res=-1;
if(bel[x]==bel[y])
{
for(int i=x;i<=y;++i)
{
if(a[i]+tag[bel[i]]<v) res=max(res,a[i]+tag[bel[i]]);
if(res==v-1) break;
}
return res;
}
else
{
for(int i=x;i<=r[bel[x]];++i)
{
if(a[i]+tag[bel[i]]<v) res=max(res,a[i]+tag[bel[i]]);
if(res==v-1) return res;
}
for(int i=l[bel[y]];i<=y;++i)
{
if(a[i]+tag[bel[i]]<v) res=max(res,a[i]+tag[bel[i]]);
if(res==v-1) return res;
}
for(int i=bel[x]+1;i<=bel[y]-1;++i)
{
if(sq[l[i]]+tag[i]>=v) continue;
int pos=lower_bound(sq+l[i],sq+r[i]+1,v-tag[i])-sq;
res=max(res,sq[pos-1]+tag[bel[pos-1]]);
if(res==v-1) return res;
}
return res;
}
}
int main()
{
//freopen("fk.in","r",stdin);
//freopen("fk.out","w",stdout);
n=read();
Bel=sqrt(n);
for(int i=1;i<=n;++i) a[i]=read(),sq[i]=a[i];
build();
for(int i=1;i<=n;++i)
{
int op=read(),l=read(),r=read(),c=read();
if(op==0) update(l,r,c);
if(op==1) printf("%d\n",query(l,r,c));
}
Byrespect_lowsmile;
}
数列分块入门 4
#include<iostream>
#include<algorithm>
#include<cmath>
#define away using
#define from namespace
#define OI std
#define Byrespect_lowsmile return 0
#define ll long long
away from OI;
const int N=5e4+5;
int n,Bel,q;
int l[N],r[N],bel[N];
ll sum[N],tag[N],a[N];
inline int read()
{
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9')
{if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')
{s=s*10+ch-'0';ch=getchar();}
return s*w;
}
void build()
{
for(int i=1;i<=Bel;++i)
l[i]=(i-1)*Bel+1,r[i]=i*Bel;
r[Bel]=n;
for(int i=1;i<=Bel;++i)
for(int j=l[i];j<=r[i];++j)
sum[i]+=a[j],bel[j]=i;
return ;
}
void update(int x,int y,int v)
{
if(bel[x]==bel[y])
{
for(int i=x;i<=y;++i) a[i]+=v,sum[bel[i]]+=v;
return ;
}
else
{
for(int i=x;i<=r[bel[x]];++i) a[i]+=v,sum[bel[i]]+=v;
for(int i=l[bel[y]];i<=y;++i) a[i]+=v,sum[bel[i]]+=v;
for(int i=bel[x]+1;i<=bel[y]-1;++i) tag[i]+=v;
return ;
}
}
ll query(int x,int y,int c)
{
ll res=0;
if(bel[x]==bel[y])
{
for(int i=x;i<=y;++i) res+=a[i]+tag[bel[i]];
return (res%(c+1));
}
else
{
for(int i=x;i<=r[bel[x]];++i) res+=a[i]+tag[bel[i]];
for(int i=l[bel[y]];i<=y;++i) res+=a[i]+tag[bel[i]];
for(int i=bel[x]+1;i<=bel[y]-1;++i) res+=sum[i]+tag[i]*(r[i]-l[i]+1);
return (res%(c+1));
}
}
int main()
{
//freopen("fk.in","r",stdin);
//freopen("fk.out","w",stdout);
n=read();
Bel=sqrt(n);
for(int i=1;i<=n;++i) a[i]=read();
build();
for(int i=1;i<=n;++i)
{
int op=read(),l=read(),r=read(),c=read();
if(op==0) update(l,r,c);
if(op==1) printf("%lld\n",query(l,r,c));
}
Byrespect_lowsmile;
}
数列分块入门 5
#include<iostream>
#include<cmath>
#define Byrespect_lowsmile return 0
#define away using
#define form namespace
#define OI std
away form OI;
const int N=5e4+5;
typedef long long ll;
int l[N],r[N],bel[N],tag[N],a[N];
ll sum[N];
int n,Bel;
inline int read()
{
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9')
{if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')
{s=s*10+ch-'0';ch=getchar();}
return s*w;
}
void build()
{
for(int i=1;i<=Bel;++i) l[i]=(i-1)*Bel+1,r[i]=i*Bel;
r[Bel]=n;
for(int i=1;i<=Bel;++i)
for(int j=l[i];j<=r[i];++j)
{
sum[i]+=a[j],bel[j]=i;
if(a[j]>1) tag[i]=1;
}
return ;
}
void rebuild(int num)
{
sum[num]=tag[num]=0;
for(int i=l[num];i<=r[num];++i)
{
sum[num]+=a[i];
if(a[i]>1) tag[num]=1;
}
return ;
}
void update(int x,int y)
{
if(bel[x]==bel[y])
{
if(!tag[bel[x]]) return ;
for(int i=x;i<=y;++i) sum[bel[i]]-=a[i],a[i]=sqrt(a[i]),sum[bel[i]]+=a[i];
rebuild(bel[x]);
}
else
{
for(int i=x;i<=r[bel[x]];++i) a[i]=sqrt(a[i]);
rebuild(bel[x]);
for(int i=l[bel[y]];i<=y;++i) a[i]=sqrt(a[i]);
rebuild(bel[y]);
for(int i=bel[x]+1;i<=bel[y]-1;++i)
{
if(!tag[i]) continue;
for(int j=l[i];j<=r[i];++j) a[j]=sqrt(a[j]);
rebuild(i);
}
}
}
ll query(int x,int y)
{
ll res=0;
if(bel[x]==bel[y])
{
for(int i=x;i<=y;++i) res+=a[i];
return res;
}
else
{
for(int i=x;i<=r[bel[x]];++i) res+=a[i];
for(int i=l[bel[y]];i<=y;++i) res+=a[i];
for(int i=bel[x]+1;i<=bel[y]-1;++i) res+=sum[i];
return res;
}
}
int main()
{
//freopen("fk.in","r",stdin);
//freopen("fk.out","w",stdout);
n=read();
Bel=sqrt(n);
for(int i=1;i<=n;++i) a[i]=read();
build();
for(int i=1;i<=n;++i)
{
int op=read(),l=read(),r=read(),c=read();
if(op==0) update(l,r);
if(op==1) printf("%lld\n",query(l,r));
}
Byrespect_lowsmile;
}