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].
Unfortunately, the longer he learns, the fewer he gets.
That means, if he reads books from l to r, he will get a[l]×L+a[l+1]×(L−1)+⋯+a[r−1]×2+a[r] (L is the length of [ l, r ] that equals to r−l+1).
Now Ryuji has q questions, you should answer him:
1. If the question type is 1, you should answer how much knowledge he will get after he reads books [ l, r ].
2. If the question type is 2, Ryuji will change the ith book's knowledge to a new value.
First line contains two integers nn and q (n, q≤100000).
The next line contains n integers represent a[i](a[i]≤1e9) .
Then in next q line each line contains three integers a, b, c, if a=1, it means question type is 1, and b, ccrepresents [ l , r ]. if a=2 , it means question type is 2 , and b, c means Ryuji changes the bth book' knowledge to c
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
题目来源
ACM-ICPC 2018 徐州赛区网络预赛
问题描述
给你一个数列a[1..n],多次求对于[i..j]区间,a[i]*L+a[i+1]*(L-1)+...+a[j]*1,其中L是区间长度(j-i+1)。或者改变某个a[i]的值。
思路
线段树求解
AC的C++代码
#include
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const int N=100010;
ll sum[N<<2],ans[N<<2],a[N];
void pushup(int l,int r,int rt)
{
int m=(l+r)>>1;
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
ans[rt]=ans[rt<<1]+ans[rt<<1|1]+(r-m)*sum[rt<<1];
}
void build(int l,int r,int rt)
{
if(l==r){
sum[rt]=a[l];
ans[rt]=a[l];
return;
}
int m=(l+r)>>1;
build(ls);
build(rs);
pushup(l,r,rt);
}
void update(int L,ll C,int l,int r,int rt)
{
if(l==r){
sum[rt]=C;
ans[rt]=C;
return;
}
int m=(l+r)>>1;
if(L<=m)
update(L,C,ls);
else
update(L,C,rs);
pushup(l,r,rt);
}
ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
return ans[rt]+sum[rt]*(R-r);
int m=(l+r)>>1;
ll res=0;
if(L<=m)
res+=query(L,R,ls);
if(R>=m+1)
res+=query(L,R,rs);
return res;
}
int main()
{
ll n,q,A,B,C;
scanf("%lld%lld",&n,&q);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,n,1);
while(q--){
scanf("%lld%lld%lld",&A,&B,&C);
if(A==1)
printf("%lld\n",query(B,C,1,n,1));
else
update(B,C,1,n,1);
}
return 0;
}