版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lingzidong/article/details/82686299
题目:https://nanti.jisuanke.com/t/31460
题意:两个操作,操作一查询
,操作二是单点修改
单点修改好说,我们先来想第一个操作,直接更新的话肯定会超时,我们不妨开两个树状数组,然后分别更新(n - i +1)*a[i], 和a[i] 的前缀和,最后拆卸你的时候就变成
至于怎么推出来的,本人是画格子画出来的……
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 1e5 + 5;
ll bit1[MAXN],bit2[MAXN],a[MAXN];
int n,q;
int lowbit(int x)
{
return x & (-x);
}
void update(int x,ll val,ll b[])
{
while(x <= n)
{
b[x] += val;
x += lowbit(x);
}
}
ll query(int x,ll b[])
{
ll res = 0;
while(x)
{
res += b[x];
x -= lowbit(x);
}
return res;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i = 1;i<=n;i++)
{
scanf("%lld",&a[i]);
update(i,a[i],bit1);
update(i,(n - i + 1)*a[i],bit2);
}
while(q--)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(x == 1)
{
ll ans1 = query(z,bit2) - query(y-1,bit2);
ll ans2 = (n - z)*(query(z,bit1) - query(y-1,bit1));
//cout<<ans1<<' '<<ans2<<endl;
printf("%lld\n",ans1 - ans2);
}
else
{
ll val = z - a[y];
update(y,val,bit1);
update(y,val*(n - y +1),bit2);
a[y] = z;
}
}
return 0;
}