1 分块1
区间加法,单点查询。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=5e4+10;
#define int long long
int read(){
int a=0,op=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') op=-1;c=getchar();}
while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
return a*op;
}
int tag[maxn],a[maxn],belong[maxn];
int n,B;
int query(int q){return a[q]+tag[belong[q]];}
void change(int l,int r,int c){
int bl=belong[l]+1,br=belong[r]-1;
if(belong[l]==belong[r]) for(int i=l;i<=r;i++) a[i]+=c;
else{
for(int i=bl;i<=br;i++) tag[i]+=c;
for(int i=l;belong[i]!=bl;i++) a[i]+=c;
for(int i=r;belong[i]!=br;i--) a[i]+=c;
}
return ;
}
#undef int
int main(){
#define int long long
n=read();
B=sqrt(n);
for(int i=1;i<=n;i++) a[i]=read(),belong[i]=(i-1)/B+1;
int t=n;
while(t--){
int w,b,c,d;
w=read(),b=read(),c=read(),d=read();
if(!w) change(b,c,d);
else printf("%lld
",query(c));
}
return 0;
}
2 分块2
区间加法,查询区间内小于(c^2)的值的个数。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=5e4+10;
#define int long long
int read(){
int a=0,op=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') op=-1;c=getchar();}
while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
return a*op;
}
int tag[maxn],a[maxn],belong[maxn];
int n,B;
vector<int> v[505];
void update(int b){
v[b].clear();
for(int i=(b-1)*B+1;belong[i]==b;i++) v[b].push_back(a[i]);
sort(v[b].begin(),v[b].end());
}
void change(int l,int r,int c){
int bl=belong[l]+1,br=belong[r]-1;
if(belong[l]==belong[r]){
for(int i=l;i<=r;i++) a[i]+=c;
update(belong[l]);
}
else{
for(int i=bl;i<=br;i++) tag[i]+=c;
for(int i=l;belong[l]==belong[i];i++) a[i]+=c;
update(belong[l]);
for(int i=r;belong[i]==belong[r];i--) a[i]+=c;
update(belong[r]);
}
}
int query(int l,int r,int c){
int res=0,bl=belong[l]+1,br=belong[r]-1;
if(belong[l]==belong[r]){
for(int i=l;i<=r;i++) res+=(a[i]<c-tag[belong[l]]);
return res;
}
for(int i=bl;i<=br;i++) res+=lower_bound(v[i].begin(),v[i].end(),c-tag[i])-v[i].begin();
for(int i=l;belong[i]==belong[l];i++) res+=(a[i]<c-tag[belong[l]]);
for(int i=r;belong[i]==belong[r];i--) res+=(a[i]<c-tag[belong[r]]);
return res;
}
#undef int
int main(){
#define int long long
n=read();
B=sqrt(n);
for(int i=1;i<=n;i++) a[i]=read(),belong[i]=(i-1)/B+1,v[belong[i]].push_back(a[i]);
int t=n;
int mb=belong[n];
for(int i=1;i<=mb;i++) sort(v[i].begin(),v[i].end());
while(t--){
int w,b,c,d;
w=read(),b=read(),c=read(),d=read();
if(!w) change(b,c,d);
else d*=d,printf("%lld
",query(b,c,d));
}
return 0;
}
3 分块3
区间加法,求区间某个点的前驱(在他之前小于该点的最大值,没有输出-1)
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
const int maxn=5e5+10;
#define int long long
int read(){
int a=0,op=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') op=-1;c=getchar();}
while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
return a*op;
}
int tag[maxn],a[maxn],belong[maxn];
int n,B;
vector<int>que[1005];
void init(){
for(int i=1;i<=belong[n];i++) sort(que[i].begin(),que[i].end());
}
void update(int x){
que[x].clear();
for(int i=(x-1)*B+1;belong[i]==x;i++) que[x].push_back(a[i]);
sort(que[x].begin(),que[x].end());
}
void modify(int l,int r,int c){
int bl=belong[l]+1,br=belong[r]-1;
if(belong[l]==belong[r]){
for(int i=l;i<=r;i++) a[i]+=c;
update(belong[l]);
return ;
}
for(int i=l;belong[l]==belong[i];i++) a[i]+=c;
for(int i=bl;i<=br;i++) tag[i]+=c;
for(int i=r;belong[i]==belong[r];i--) a[i]+=c;
update(belong[l]),update(belong[r]);
}
int find(int a,int c){
vector<int>::iterator it=lower_bound(que[a].begin(),que[a].end(),c-tag[a]);
if(it==que[a].begin()) return -1;
else {--it;return *it+tag[a];}
}
int query(int l,int r,int c){
int res=-1;
int bl=belong[l]+1,br=belong[r]-1;
if(belong[l]==belong[r]){
for(int i=l;i<=r;i++) if(a[i]+tag[belong[l]]<c) res=max(res,a[i]+tag[belong[l]]);
return res;
}
for(int i=bl;i<=br;i++) res=max(res,find(i,c));
for(int i=l;belong[l]==belong[i];i++) if(a[i]+tag[belong[l]]<c) res=max(res,a[i]+tag[belong[l]]);
for(int i=r;belong[r]==belong[i];i--) if(a[i]+tag[belong[r]]<c) res=max(res,a[i]+tag[belong[r]]);
return res;
}
#undef int
int main(){
#define int long long
n=read();
B=sqrt(n);
for(int i=1;i<=n;i++) a[i]=read(),belong[i]=(i-1)/B+1,que[belong[i]].push_back(a[i]);
int t=n;
init();
while(t--){
int w,b,c,d;
w=read(),b=read(),c=read(),d=read();
if(!w) modify(b,c,d);
else printf("%lld
",query(b,c,d));
}
return 0;
}
分块4
区间加法,区间求和。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=5e5+10;
int sum[maxn];
#define int long long
int read(){
int a=0,op=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') op=-1;c=getchar();}
while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
return a*op;
}
int tag[maxn],a[maxn],belong[maxn];
int n,B;
void add(int l,int r,int c){
int bl=belong[l]+1,br=belong[r]-1;
for(int i=l;i<=min(belong[l]*B,r);i++) a[i]+=c,sum[belong[i]]+=c;
if(belong[l]!=belong[r]){
for(int i=r;i>=(belong[r]-1)*B+1;i--) a[i]+=c,sum[belong[i]]+=c;
}
for(int i=bl;i<=br;i++) tag[i]+=c;
}
int query(int l,int r){
int ans=0;
int bl=belong[l]+1,br=belong[r]-1;
for(int i=l;i<=min(belong[l]*B,r);i++) ans+=a[i]+tag[belong[i]];
if(belong[l]!=belong[r]){
for(int i=r;i>=(belong[r]-1)*B+1;i--) ans+=a[i]+tag[belong[i]];
}
for(int i=bl;i<=br;i++) ans+=sum[i]+B*tag[i];
return ans;
}
#undef int
int main(){
#define int long long
n=read();
B=sqrt(n);
for(int i=1;i<=n;i++) a[i]=read(),belong[i]=(i-1)/B+1,sum[belong[i]]+=a[i];
int t=n;
while(t--){
int w,b,c,d;
w=read(),b=read(),c=read(),d=read();
if(!w) add(b,c,d);
else printf("%lld
",query(b,c)%(d+1));
}
return 0;
}
5 分块5
区间求和,区间元素开根号(下取整)
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=5e5+10;
int sum[maxn];
#define int long long
int read(){
int a=0,op=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') op=-1;c=getchar();}
while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
return a*op;
}
int tag[maxn],a[maxn],belong[maxn];
int n,B;
int flag[maxn];
void solve_sqrt(int x){
if(flag[x]) return ;
flag[x]=1;
sum[x]=0;
for(int i=(x-1)*B+1;i<=B*x;i++){
a[i]=sqrt(a[i]),sum[x]+=a[i];
if(a[i]>1) flag[x]=0;
}
}
void add(int l,int r,int c){
int bl=belong[l]+1,br=belong[r]-1;
for(int i=l;i<=min(belong[l]*B,r);i++) sum[belong[l]]-=a[i],a[i]=sqrt(a[i]),sum[belong[l]]+=a[i];
if(belong[l]!=belong[r]){
for(int i=r;i>=(belong[r]-1)*B+1;i--) sum[belong[r]]-=a[i],a[i]=sqrt(a[i]),sum[belong[i]]+=a[i];
}
for(int i=bl;i<=br;i++) solve_sqrt(i);
}
int query(int l,int r){
int ans=0;
int bl=belong[l]+1,br=belong[r]-1;
for(int i=l;i<=min(belong[l]*B,r);i++) ans+=a[i];
if(belong[l]!=belong[r]){
for(int i=r;i>=(belong[r]-1)*B+1;i--) ans+=a[i];
}
for(int i=bl;i<=br;i++) ans+=sum[i];
return ans;
}
#undef int
int main(){
#define int long long
n=read();
B=sqrt(n);
for(int i=1;i<=n;i++) a[i]=read(),belong[i]=(i-1)/B+1,sum[belong[i]]+=a[i];
int t=n;
while(t--){
int w,b,c,d;
w=read(),b=read(),c=read(),d=read();
if(!w) add(b,c,d);
else printf("%lld
",query(b,c));
}
return 0;
}
6 分块6
单点插入,单点查询。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=5e5+10;
int sum[maxn];
#define int long long
int read(){
int a=0,op=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') op=-1;c=getchar();}
while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
return a*op;
}
int tag[maxn],a[maxn],belong[maxn];
int n,m,B;
int flag[maxn];
int st[maxn],top;
vector<int> ve[maxn];
pair<int,int> query(int b){
int x=1;
while(b>ve[x].size()) b-=ve[x].size(),x++;
return make_pair(x,b-1);
}
void rebuild(){
top=0;
for(int i=1;i<=m;i++){
for(vector<int>::iterator j=ve[i].begin();j!=ve[i].end();j++)
st[++top]=*j;
ve[i].clear();
}
int blo2=sqrt(top);
for(int i=1;i<=top;i++) ve[(i-1)/blo2+1].push_back(st[i]);
m=(top-1)/blo2+1;
}
void insertt(int a,int b){
pair<int,int> t=query(a);
ve[t.first].insert(ve[t.first].begin()+t.second,b);
if(ve[t.first].size()>20*B) rebuild();
}
#undef int
int main(){
#define int long long
n=read();
B=sqrt(n);
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) ve[(i-1)/B+1].push_back(a[i]);
m=(n-1)/B+1;
int t=n;
while(t--){
int w,b,c,d;
w=read(),b=read(),c=read(),d=read();
if(!w) insertt(b,c);
else{
pair<int,int> t=query(c);printf("%lld
",ve[t.first][t.second]);
}
}
return 0;
}
7 分块7
区间加法,区间乘法,单点查询。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=5e5+10;
const int mod=1e4+7;
int sum[maxn];
#define int long long
int read(){
int a=0,op=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') op=-1;c=getchar();}
while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
return a*op;
}
int addtag[maxn],multag[maxn],a[maxn],belong[maxn];
int n,m,B;
void reset(int x){
for(int i=(x-1)*B+1;i<=min(n,x*B);i++) a[i]=(a[i]*multag[x]+addtag[x])%mod;
addtag[x]=0,multag[x]=1;
}
int query(int q){return (a[q]*multag[belong[q]]+addtag[belong[q]])%mod;}
void add_change(int l,int r, int c){
reset(belong[l]);
int bl=belong[l]+1,br=belong[r]-1;
for(int i=l;i<=min(belong[l]*B,r);i++) a[i]+=c,a[i]%=mod;
if(belong[l]!=belong[r]){
reset(belong[r]);
for(int i=r;i>=(belong[r]-1)*B+1;i--) a[i]+=c,a[i]%=mod;
}
for(int i=bl;i<=br;i++) addtag[i]+=c,addtag[i]%=mod;
}
void mul_change(int l,int r,int c){
reset(belong[l]);
int bl=belong[l]+1,br=belong[r]-1;
for(int i=l;i<=min(belong[l]*B,r);i++) a[i]*=c,a[i]%=mod;
if(belong[l]!=belong[r]){
reset(belong[r]);
for(int i=r;i>=(belong[r]-1)*B+1;i--) a[i]*=c,a[i]%=mod;
}
for(int i=bl;i<=br;i++) addtag[i]*=c,addtag[i]%=mod,multag[i]*=c,multag[i]%=mod;
}
#undef int
int main(){
#define int long long
n=read();
B=sqrt(n);
for(int i=1;i<=n;i++) a[i]=read(),belong[i]=(i-1)/B+1;
for(int i=1;i<=belong[n];i++) multag[i]=1;
int t=n;
while(t--){
int w,b,c,d;
w=read(),b=read(),c=read(),d=read();
if(w==0) add_change(b,c,d);
else if(w==1) mul_change(b,c,d);
else printf("%lld
",query(c)%mod);
}
return 0;
}
8 分块8
区间查询等于c的元素个数,并将区间内的元素改为c
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=5e5+10;
const int mod=1e4+7;
int sum[maxn];
#define int long long
int read(){
int a=0,op=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') op=-1;c=getchar();}
while(c>='0'&&c<='9') a*=10,a+=c^48,c=getchar();
return a*op;
}
int tag[maxn],a[maxn],belong[maxn];
int n,m,B;
void reset(int x){
if(tag[x]==-1) return ;
for(int i=(x-1)*B+1;i<=x*B;i++) a[i]=tag[x];
tag[x]=-1;
}
int solve(int l,int r,int c){
int ans=0,bl=belong[l]+1,br=belong[r]-1;
reset(belong[l]);
for(int i=l;i<=min(r,B*belong[l]);i++){
if(a[i]!=c) a[i]=c;
else ans++;
}
if(belong[l]!=belong[r]){
reset(belong[r]);
for(int i=r;i>=(belong[r]-1)*B+1;i--){
if(a[i]!=c) a[i]=c;
else ans++;
}
}
for(int i=bl;i<=br;i++){
if(tag[i]!=-1){
if(tag[i]!=c) tag[i]=c;
else ans+=B;
}
else{
for(int j=(i-1)*B+1;j<=i*B;j++){
if(a[j]!=c) a[j]=c;
else ans++;
}
tag[i]=c;
}
}
return ans;
}
#undef int
int main(){
#define int long long
memset(tag,-1,sizeof(tag));
n=read();
B=sqrt(n);
for(int i=1;i<=n;i++) a[i]=read(),belong[i]=(i-1)/B+1;
int t=n;
while(t--){
int w,b,c,d;
b=read(),c=read(),d=read();
printf("%lld
",solve(b,c,d));
}
return 0;
}