题目
思路
利用差分思想
先将数组变为差分数列,即
c
i
=
a
i
−
a
i
−
1
c_i=a_i-a_{i-1}
ci=ai−ai−1,然后对于两个操作:
第
x
x
x个数的值为
c
1
c_1
c1到
c
i
c_i
ci的和
将区间(x,y)加c,相当于在
c
x
c_x
cx加c,并在
c
y
+
1
c_{y+1}
cy+1减c。
再用树状数组优化求解。
代码
#include<iostream>
#define ll long long
using namespace std;
const int M=200000;
ll c[M+100],n,a[M+100],t,o,x,y,w,q;
void up(ll x,ll y)
{
for(; x<=n; x+=x&-x) c[x]+=y;
}
ll sum(ll x)
{
ll ans=0;
for(; x; x-=x&-x) ans+=c[x];
return ans;
}
int main()
{
scanf("%lld%lld",&n,&q);
for(int i=1; i<=n; ++i)
{
scanf("%lld",&a[i]);
t=a[i]-a[i-1];//差分
up(i,t);
}
for(int i=1; i<=q; ++i)
{
scanf("%lld",&o);
if(o==1)
{
scanf("%lld%lld%lld",&x,&y,&w);
up(x,w);//将差分数列第x位加 w
up(y+1,-w);//第y位减w
//其效果等于将区间(x,y)加 w
}
else
{
scanf("%lld",&x);
{
printf("%lld\n",sum(x));
}
}
}
}