分块(优雅的暴力) 学习博客。。。持续更新
作者:互联网
学习参照以下两个博客:分块——优雅的暴力 分块入门1~9
分块入门1:
给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,单点查值。
//给定一个长为n的序列,以及n个操作,操作涉及区间加法,单点查值
#include<bits/stdc++.h>
using namespace std;
const int maxn = 50086;
int a[maxn],n,m;
int add[maxn];
int pos[maxn];//,sum[maxn];
int L[maxn],R[maxn];
inline void change(int l,int r,int d){
int p = pos[l], q = pos[r];
if(p==q)//如果要修改的区间在同一个块里面
for(int i=l;i<=r;++i) a[i]+=d;
else {//如果要修改的区间不在同一个块里面
for(int i=p+1;i<=q-1;++i) add[i] += d;//直接给块赋值
for(int i=l;i<=R[p];i++) a[i]+=d;
for(int i=L[q];i<=r;++i) a[i]+=d;
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
int t = sqrt(n);//分为t块
for(int i=1;i<=t;++i){//开始分块,完整块
L[i] = (i-1)*t + 1;
R[i] = i*t;
}
if(R[t]<n) t++,L[t]=R[t-1]+1,R[t]=n;//不完整块
for(int i=1;i<=t;i++){//每个元素在块的位置
for(int j=L[i];j<=R[i];j++){
pos[j]=i;
}
}
for(int i=1;i<=m;++i){
int opt, l, r, c;
cin>>opt;
if(!opt) {
cin>>l>>r>>c;
change(l,r,c);
}
else {
cin>>r;
int q = pos[r];
cout<<a[r] + add[q]<<endl;
}
}
}
标签:opt,长为,分块,int,pos,博客,优雅,maxn 来源: https://blog.csdn.net/qq_42129242/article/details/94735039