【LOJ#6277】数列分块1

题目大意:维护一个长度为 N 的序列,支持区间修改、单点查询。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=5e4+10;
const int maxb=800;

int n,m,a[maxn];
struct node{
	int l,r,add;
}b[maxb];
int tot,bl[maxn];
void make_block(){
	tot=sqrt(n);
	for(int i=1;i<=tot;i++)b[i].l=b[i-1].r+1,b[i].r=i*tot;
	if(b[tot].r<n)++tot,b[tot].l=b[tot-1].r+1,b[tot].r=n;
	for(int i=1;i<=tot;i++)for(int j=b[i].l;j<=b[i].r;j++)bl[j]=i;
}
void modify(int l,int r,int c){
	int x=bl[l],y=bl[r];
	if(x==y){for(int i=l;i<=r;i++)a[i]+=c;}
	else{
		for(int i=x+1;i<=y-1;i++)b[i].add+=c;
		for(int i=l;i<=b[x].r;i++)a[i]+=c;
		for(int i=b[y].l;i<=r;i++)a[i]+=c;
	}
}

int main(){
	n=m=read();
	for(int i=1;i<=n;i++)a[i]=read();
	make_block();
	while(m--){
		int opt=read(),l=read(),r=read(),c=read();
		if(opt==0)modify(l,r,c);
		else if(opt==1)printf("%lld\n",a[r]+b[bl[r]].add);
	}
	return 0;
}
posted @ 2019-03-28 10:32  shellpicker  阅读(112)  评论(0编辑  收藏  举报