分块区间加和单点查询
给出一个长为 n 的数列,以及 m 个操作,操作涉及区间加法,单点查值。
输入格式
第一行输入一个数字 。
第二行输入 个数字,第 个数字为 ,以空格隔开。
接下来输入 行询问,每行输入四个数字 、、、,以空格隔开。
若 ,表示将位于 的之间的数字都加 。
若 ,表示询问 的值( 和 忽略)。
#pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> using namespace std; typedef long long ll; template <typename Tp> void read(Tp &x){ x=0;char ch=1;int fh; while(ch!='-'&&(ch>'9'||ch<'0')){ ch=getchar(); } if(ch=='-'){ fh=-1;ch=getchar(); }else fh=1; while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+ch-'0';ch=getchar(); } x*=fh; } inline char read1() { register char ch=getchar(); while(ch<'A'||ch>'M')ch=getchar(); return ch; } const int maxn=1e6+100; int a[maxn],l[maxn],d[maxn],r[maxn],belong[maxn],lazy[maxn],ans; int n,q,block,tot,x,y,k,op; void build(){ block=sqrt(n); tot=n/block; if(n%block){ tot++; } for(register int i=1;i<=n;i++){ belong[i]=(i-1)/block+1;d[i]=a[i]; } for(register int i=1;i<=tot;i++){ l[i]=(i-1)*block+1; r[i]=i*block; } r[tot]=n; } void change(){ if(belong[x]==belong[y]){ for(int i=x;i<=y;i++){ a[i]+=k; } } else{ for(register int i=x;i<=r[belong[x]];i++){ a[i]+=k; } for(register int i=l[belong[y]];i<=y;i++){ a[i]+=k; } for(register int i=belong[x]+1;i<belong[y];i++){ lazy[i]+=k; } } } int main(){ read(n); for(register int i=1;i<=n;i++){ read(a[i]); } build(); for(register int i=1;i<=n;i++){ read(op); read(x),read(y),read(k); if(op==0){ change(); } else if(op==1){ printf("%d\n",a[y]+lazy[belong[y]]); } } return 0; }