数列分块入门 1
程序员文章站
2022-09-30 18:52:29
题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及区间加法,单点查值。 题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及区间加法,单点查值。 题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及区间加法,单点查值。 给出一个长为 nnn 的 ......
题目描述
输入格式
输出格式
思路:
最简单的数列分块
先明确一波分块的概念:
将一个长为n数列拆成k块儿(一般k=sqrt(n));
然后对区间的修改变为对完整块的修改和对区间两端不完整块的暴力
那如何描述对区间的修改和查询呢?
lazy大法好!!
建一个标记数组,存储对整个区间的修改
最后输出标记数组与原值的和即可
代码:
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int x[50005],sy[50005],fk[50005],n,opt,l,r,c,a,b,d,dx,cnt,bnt; int main() { // freopen("a1.in","r",stdin); // freopen("1.out","w",stdout); cin>>n; dx=sqrt(n); bnt=1; for(a=1;a<=n;a++) { scanf("%d",&x[a]); sy[a]=(a-1)/dx+1; } for(a=1;a<=n;a++) { scanf("%d%d%d%d",&opt,&l,&r,&c); if(opt==1) { printf("%d\n",x[r]+fk[sy[r]]); } else { if(sy[l]==sy[r]) { for(b=l;b<=r;b++) { x[b]+=c; } continue; } int lf,ri; lf=sy[l]; ri=sy[r]; for(b=l;b<=lf*dx;b++) { x[b]+=c; } for(b=(ri-1)*dx+1;b<=r;b++) { x[b]+=c; } for(b=lf+1;b<=ri-1;b++) { fk[b]+=c; } } } }