Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, each book has its knowledge a[i]a[i]a[i].
Unfortunately, the longer he learns, the fewer he gets.
That means, if he reads books from lll to rrr, he will get a[l]×L+a[l+1]×(L−1)+⋯+a[r−1]×2+a[r]a[l] \times L + a[l+1] \times (L-1) + \cdots + a[r-1] \times 2 + a[r]a[l]×L+a[l+1]×(L−1)+⋯+a[r−1]×2+a[r] (LLL is the length of [ lll, rrr ] that equals to r−l+1r - l + 1r−l+1).
Now Ryuji has qqq questions, you should answer him:
111. If the question type is 111, you should answer how much knowledge he will get after he reads books [ lll, rrr ].
222. If the question type is 222, Ryuji will change the ith book's knowledge to a new value.
Input
First line contains two integers nnn and qqq (nnn, q≤100000q \le 100000q≤100000).
The next line contains n integers represent a[i](a[i]≤1e9)a[i]( a[i] \le 1e9)a[i](a[i]≤1e9) .
Then in next qqq line each line contains three integers aaa, bbb, ccc, if a=1a = 1a=1, it means question type is 111, and bbb, ccc represents [ lll , rrr ]. if a=2a = 2a=2 , it means question type is 222 , and bbb, ccc means Ryuji changes the bth book' knowledge to ccc
Output
For each question, output one line with one integer represent the answer.
样例输入复制
5 3 1 2 3 4 5 1 1 3 2 5 0 1 4 5
样例输出复制
10 8
题目来源
题目大意:n个数,q次操作,每次操作分两种,当ope=1时查询区间[l,r]的和=a[l]*(r-l+1)+a[l+1]*(r-l)...a[r];当ope==2时,数组在位置i的数字变成了新的数字。
分析:
用两个树状数组来维护,一个维护a[1]+a[2]+...+a[n]的和,另一个来维护n*a[1]+(n-1)*a[2]+...a[n]的和。
最终查询区间的结果就是第二个树状数组的区间和-(n-r)*第一个树状数组的区间和。(拿一个查询区间画一下就可以知道了)
代码:
#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
const int maxn=1e5+10;
typedef long long ll;
ll n,q;
ll a[maxn];
void add(ll x,ll val,ll ans[]) ///更新
{
while(x<=n)
{
ans[x]+=val;
x+=lowbit(x);
}
}
ll qury(ll x,ll ans[]) ///查询
{
ll res=0;
while(x>0)
{
res+=ans[x];
x-=lowbit(x);
}
return res;
}
int main()
{
while(~scanf("%d%d",&n,&q))
{
ll sum[maxn];
ll sum1[maxn];
memset(sum1,0,sizeof(sum1));
memset(sum,0,sizeof(sum));
for(ll i=1; i<=n; i++)
{
scanf("%lld",&a[i]);
add(i,a[i],sum);
add(i,(n-i+1)*a[i],sum1);
}
for(ll i=1; i<=q; i++)
{
ll ope;
scanf("%lld",&ope);
if(ope==1)
{
ll l,r;
scanf("%lld%lld",&l,&r);
printf("%lld\n",qury(r,sum1)-qury(l-1,sum1)-(n-r)*(qury(r,sum)-qury(l-1,sum)));
}
else
{
ll pos,val;
scanf("%lld%lld",&pos,&val);
add(pos,val-a[pos],sum);
add(pos,(n-pos+1)*(val-a[pos]),sum1);
a[pos]=val;
}
}
}
return 0;
}