目录:
题意:
给出两种操作:一个是对指定区间每个数进行加法,另个是求指定数当前的值
分析:
这题其实跟P3367是差不多的
但是需要用到差分:
来介绍一下差分
设数组a={1,6,8,5,10},那么差分数组b={1,5,2,-3,5}
也就是说b[i]=a[i]-a[i-1];(a[0]=0;),那么a[i]=b[1]+….+b[i];(这个很好证的)。
假如区间[2,4]都加上2的话
a数组变为a={1,8,10,7,10},b数组变为b={1,7,2,-3,3};
发现了没有,b数组只有b[2]和b[5]变了,因为区间[2,4]是同时加上2的,所以在区间内b[i]-b[i-1]是不变的
所以对区间[x,y]进行修改,只用修改b[x]与b[y+1]:
b[x]=b[x]+k;b[y+1]=b[y+1]-k
而我们对区间进行加法,设是给x~y加w,那我们其实是对1~x加w,而对x+1~y减w,最后输出的话,跟P3367相差无几
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
int c[500001];
int n=read(),m=read();
int lowbit(int x)
{
return x&(-x);
}
void change(int k,int delta)
{
while(k<=n)
{
c[k]+=delta;
k+=lowbit(k);
}
return;
}
int t;
int getsum(int k)
{
t=0;
while(k>0)
{
t+=c[k];
k-=lowbit(k);
}
return t;
}
int main()
{
int tf,x,y,ago=0,w;
for(int i=1;i<=n;i++)
{
w=read();
change(i,w-ago);//跟分析一样
ago=w;
}
for(int i=1;i<=m;i++)
{
tf=read();
if(tf==1)
{
x=read();y=read();w=read();
change(y+1,-w);//跟小编分析的同理
change(x,w);
}
else
{
x=read();
printf("%d\n",getsum(x));//直接求解
}
}
return 0;
}