#include<iostream>
#include<cstdio>
using namespace std;
int n,m,a[1000004];
struct data{int l,r,val,lazy,len;}tr[2*1000004];
void build(int k,int s,int t) {//建树
tr[k].l=s;tr[k].r=t;tr[k].len=t-s+1;
if(s==t) {tr[k].val=a[s];return;}
int mid=(s+t)>>1;
build(k<<1,s,mid);
build(k<<1|1,mid+1,t);
tr[k].val=tr[k<<1].val+tr[k<<1|1].val;
}
//区间修改
void pushdown(int k){
if(!tr[k].lazy) return;
int p=tr[k].lazy;
tr[k<<1].lazy+=p;
tr[k<<1|1].lazy+=p;
tr[k<<1].val+=tr[k<<1].len*p;
tr[k<<1|1].val+=tr[k<<1|1].len*p;
tr[k].lazy=0;
}
void update(int k,int l,int r,int addval){
int ll=tr[k].l,rr=tr[k].r;
if(ll>=l && rr<=r){
tr[k].lazy+=addval;
tr[k].val+=tr[k].len*addval;
return;
}
int mid=(ll+rr)>>1;
if (tr[k].lazy) pushdown(k);
if(l<=mid) update(k<<1,l,min(r,mid),addval);
if(r>mid) update(k<<1|1,max(l,mid+1),r,addval);
tr[k].val=tr[k<<1].val+tr[k<<1|1].val;
}
int query1(int k,int x){//单点查询
int ll=tr[k].l,rr=tr[k].r;
if(ll==rr) return tr[k].val;
int mid=(ll+rr)>>1;
if (tr[k].lazy) pushdown(k);
if(x<=mid) return query1(k<<1,x);
else return query1(k<<1|1,x);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
scanf("%d",&m);
for(int i=1;i<=m;i++){
int flag;scanf("%d",&flag);
int x,y,z;scanf("%d",&x);
if(flag==1) scanf("%d%d",&y,&z),update(1,x,y,z);
else printf("%d\n",query1(1,x));
}
return 0;
}
Laoj1298
输入格式
第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少。
输出格式
对于每个询问输出一行一个答案
输入示例
3
1
2
3
2
1 2 3 2
2 3
输出示例
5