一:单点修改,区间查询
//单点修改,区间查询
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
vector<ll>a(5e5+5),b(5e5+5);
ll n,k;
ll lowbit(ll x)
{
return x&(-x);
}
void add(ll x,ll y)
{
for(ll i=x;i<=n;i+=lowbit(i))
{
b[i]+=y;
}
}
void query(ll x,ll y)//前缀和相减求区间和
{
ll sum=0;
for(ll i=x-1;i;i-=lowbit(i))
{
sum-=b[i];
}
for(ll i=y;i;i-=lowbit(i))
{
sum+=b[i];
}
cout<<sum<<'\n';
}
void solve()
{
cin>>n>>k;
for(ll i=1;i<=n;i++)
{
cin>>a[i];
add(i,a[i]);//该节点与父节点及右侧2的幂的点都加上该数,利于求区间和
}
ll t,x,y;
while(k--)
{
cin>>t>>x>>y;
if(t==1)
{
add(x,y);//同理
}
else{
query(x,y);//前缀和差
//cout<<query(x,y)<<'\n';
}
}
}
int main()
{
//ll t;cin>>t;
//while(t--)
solve();
}
二://区间修改,查询单点
//区间修改,查询单点
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll n,m;
ll c[500005],a[500005];
ll lowbit(ll x)
{
return x&(-x);
}
void add(ll x,ll z)
{
for(ll i=x;i<=n;i+=lowbit(i))
{
c[i]+=z;
}
}
ll query(ll x)
{
ll sum=0;
for(ll i=x;i;i-=lowbit(i))//差分前缀和
{
sum+=c[i];
}
return sum;
}
void solve()
{
cin>>n>>m;
for(ll i=1;i<=n;i++)
{
cin>>a[i];
add(i,a[i]-a[i-1]);//差分数组
}
ll t,x,y,z;
while(m--)
{
cin>>t;
if(t==1)
{
cin>>x>>y>>z;
add(x,z);//原本差分数组只用修改一次,但是其含有多级父节点,故需要多次修改
add(y+1,-z);
}
else{
cin>>x;
cout<<query(x)<<'\n';//差分前缀和
}
}
}
int main()
{
//ll t;cin>>t;
//while(t--)
solve();
return 0;
}
三: //区间修改,区间查询
基于二的模板,最后求的是区间的值!!
// ****n *(c[1]+c[2]+……+c[n])-(0 *c[1]+1 *c[2]+...+(n-1)*c[n])*****
//区间修改,区间查询
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll n,m;
ll c[100005],a[100005],b[100005];
ll lowbit(ll x)
{
return x&(-x);
}
///
void add(ll x,ll z)
{
for(ll i=x;i<=n;i+=lowbit(i))
{
c[i]+=z;
}
}
///
void added(ll x,ll z)
{
for(ll i=x;i<=n;i+=lowbit(i))
{
b[i]+=z;
}
}
/
ll query(ll x)
{
ll sum=0;
for(ll i=x;i;i-=lowbit(i))
{
sum+=c[i];
}
return sum;
}
/
ll queryed(ll x)
{
ll sum=0;
for(ll i=x;i;i-=lowbit(i))
{
sum+=b[i];
}
return sum;
}
/
void solve()
{
cin>>n>>m;
for(ll i=1;i<=n;i++)
{
cin>>a[i];
add(i,a[i]-a[i-1]);//差分数组
added(i,(i-1)*(a[i]-a[i-1]));//待减差分数组,即:(0 *c[1]+1 *c[2]+...+(n-1)*c[n]);
}
ll t,x,y,z;
while(m--)
{
cin>>t;
if(t==1)
{
cin>>x>>y>>z;
add(x,z);//多级父节点,故需要多次修改,为了使用前缀和
add(y+1,-z);
added(x,z*(x-1));
//同理:即 (0 *c[1]+1 *c[2]+...+(n-1)*c[n]);
added(y+1,-z*(y));
}
else{
cin>>x>>y;
ll sum1=0,sum2=0;
sum1=(x-1)*query(x-1)-queryed(x-1);//a[x-1]的前缀和
sum2=y*query(y)-queryed(y);//a[y]的前缀和
//即:*****n *(c[1]+c[2]+……+c[n])-(0 *c[1]+1 *c[2]+...+(n-1)*c[n])*****
cout<<sum2-sum1<<'\n';
}
}
}
int main()
{
//ll t;cin>>t;
//while(t--)
solve();
return 0;
}