题解:P13976 数列分块入门 1
Defy_HeavenS · · 题解
可以参考我的分块合集 分块。
#6277. 数列分块入门 1 - 题目 - LibreOJ
题面
给出一个长为
技巧
区间加法需要一个标记
时间复杂度。设块长为
代码
#include<bits/stdc++.h>
#define umap unordered_map
#define uset unordered_set
#define mset multiset
#define yes cout<<"Yes\n"
#define no cout<<"No\n"
#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define tmax(a,b) (a)=max((a),(b))
#define tmin(a,b) (a)=min((a),(b))
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL N=3e5+5,M=555;
LL n,a[N],T,tot,be[M],en[M],bel[N],tag[N];
void init(){
T=tot=sqrt(n);
for(LL i=1;i<=tot;i++){
be[i]=en[i-1]+1,en[i]=i*T;
}
en[tot]=n;
for(LL i=1;i<=tot;i++){
for(LL j=be[i];j<=en[i];j++){
bel[j]=i;
}
}
}
void update(LL l,LL r,LL val){
if(bel[l]==bel[r]){
for(LL i=l;i<=r;i++){
a[i]+=val;
}
return;
}
for(LL i=l;i<=en[bel[l]];i++){
a[i]+=val;
}
for(LL i=be[bel[r]];i<=r;i++){
a[i]+=val;
}
for(LL i=bel[l]+1;i<=bel[r]-1;i++){
tag[i]+=val;
}
}
LL query(LL pos){
return a[pos]+tag[bel[pos]];
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n;
for(LL i=1;i<=n;i++){
cin>>a[i];
}
init();
for(LL i=1,op,l,r,c;i<=n;i++){
cin>>op>>l>>r>>c;
if(op){
cout<<query(r)<<"\n";
}else{
update(l,r,c);
}
}
return 0;
}