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].
Unfortunately, the longer he learns, the fewer he gets.
That means, if he reads books from ll to rr, he will get 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] (LL is the length of [ ll, rr ] that equals to r - l + 1r−l+1).
Now Ryuji has qq questions, you should answer him:
11. If the question type is 11, you should answer how much knowledge he will get after he reads books [ ll, rr ].
22. If the question type is 22, Ryuji will change the ith book's knowledge to a new value.
Input
First line contains two integers nn and qq (nn, q \le 100000q≤100000).
The next line contains n integers represent a[i]( a[i] \le 1e9)a[i](a[i]≤1e9) .
Then in next qq line each line contains three integers aa, bb, cc, if a = 1a=1, it means question type is 11, and bb, ccrepresents [ ll , rr ]. if a = 2a=2 , it means question type is 22 , and bb, cc means Ryuji changes the bth book' knowledge to cc
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个询问,输入a,b,c,若a=1,表示根据题目公式求出求b~c的和,若a=2,将a[b]的值更换为c;
//思路:线段树; 我们发现,在【L,R】的a数组求和时,a[index]的前缀qz1=(R-L+1)-(index-L);假如【L,R】由【L,R1】和【L1,R】组成,那么,【L,R1】中啊a[index]的qz2=(R1-L+1)-(index-L),那么,【L,R】求和时其中的【L,R1】的a[index]的qz,和【L,R1】求和时a[index]的前缀,的差为qz1-qz2=R-R1;sum1[L,R1]=sum2[L,R1]+(R-R1)*(a[L]+a[L+1]+......a[R1]); 同理,
sum1[L1,R]=sum2[L1,R]+(R-R)*(a[L]+a[L+1]+......a[R1])=sum2[L1,R]+(R-R);
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const ll MAX=1e5+10;
struct node
{
int l;
int r;
ll val;//保存根据公式求和的值;
ll sum;//保存a[1]+a[2]+a[3]+...的值;
}tree[4*MAX];
ll a[MAX];
ll n,q;
void pushUp(ll root)
{
tree[root].val=tree[root*2].val+tree[root*2+1].val;
tree[root].sum=tree[root*2].sum+(tree[root].r-tree[root*2].r)*tree[root*2].val+tree[root*2+1].sum;
}
void build(ll root,ll L,ll R)
{
tree[root].l=L;
tree[root].r=R;
if(L==R)
{
tree[root].val=a[L];
tree[root].sum=a[L];
return ;
}
ll mid=(L+R)/2;
build(root*2,L,mid);
build(root*2+1,mid+1,R);
pushUp(root);
return;
}
void updateone(ll root,ll index,ll addval)
{
if(tree[root].l==tree[root].r)
{
tree[root].val=addval;
tree[root].sum=addval;
return ;
}
ll mid=(tree[root].l+tree[root].r)/2;
if(index<=mid)updateone(root*2,index,addval);
else updateone(root*2+1,index,addval);
//tree[root].sum+=(1+tree[root].r-index)*(addval-a[index]);
//tree[root].val+=(addval-a[index]);
pushUp(root);
return ;
}
ll query(ll root,ll L,ll R)
{
if(L<=tree[root].l&&tree[root].r<=R)
{
return tree[root].sum+(R-tree[root].r)*tree[root].val;
}
ll mid=(tree[root].l+tree[root].r)/2;
ll ans=0;
if(L<=mid)ans+=query(root*2,L,R);
if(R>mid)ans+=query(root*2+1,L,R);
return ans;
}
int main()
{
scanf("%lld%lld",&n,&q);
for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);
build(1,1,n);
while(q--)
{
ll op,b;
ll c;
scanf("%lld%lld%lld",&op,&b,&c);
if(op==1)
printf("%lld\n",query(1,b,c));
else if(op==2)
{
updateone(1,b,c);
}
}
return 0;
}