rt.为了练习我的线段树我才写这道,所以使用线段树解法。
#include<bits/stdc++.h>
using namespace std;
const int N=500005;
int n,m,a[N];
struct tree{
long long val,tag;
}tr[N<<2];
void Push_Up(int rt){tr[rt].val=tr[rt<<1].val+tr[rt<<1|1].val;}
void Push_Down(int rt,int l,int r)
{
int mid=l+r>>1;
tr[rt<<1].tag=tr[rt].tag;
tr[rt<<1|1].tag=tr[rt].tag;
tr[rt<<1].val+=tr[rt].tag*(mid-l+1);
tr[rt<<1|1].val+=tr[rt].tag*(r-mid);
tr[rt].tag=0;
}
void Build(int rt,int l,int r)
{
if(l==r)
{
tr[rt].val=a[l];
return;
}
int mid=l+r>>1;
Build(rt<<1,l,mid);
Build(rt<<1|1,mid+1,r);
Push_Up(rt);
}
void Update(int rt,int l,int r,int x,int y,long long k)
{
if(l==x&&r==y)
{
tr[rt].val+=k*(r-l+1);
tr[rt].tag+=k;
return;
}
int mid=l+r>>1;
Push_Down(rt,l,r);
if(y<=mid) Update(rt<<1,l,mid,x,y,k);
else if(x>mid) Update(rt<<1|1,mid+1,r,x,y,k);
else
{
Update(rt<<1,l,mid,x,mid,k);
Update(rt<<1|1,mid+1,r,mid+1,y,k);
}
Push_Up(rt);
}
int Query(int rt,int l,int r,int x)
{
if(l==r&&r==x) return tr[rt].val;
int mid=l+r>>1;
Push_Down(rt,l,r);
if(x<=mid) return Query(rt<<1,l,mid,x);
else return Query(rt<<1|1,mid+1,r,x);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
Build(1,1,n);
while(m--)
{
int opt,x,y;
long long k;
cin>>opt>>x;
if(opt==1) cin>>y>>k,Update(1,1,n,x,y,k);
else cout<<Query(1,1,n,x)<<endl;
}
return 0;
}