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:
If the question type is 111, you should answer how much knowledge he will get after he reads books [ lll, rrr ].
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 aia[i]( a[i] \le 1e9)ai .
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
题目来源
ACM-ICPC 2018 徐州赛区网络预赛
给定一个数组 a[N] a [ N ] ,有两种操作,
操作1,给定 l,r,查询a[l]×L+a[l+1]×(L−1)+⋯+a[r−1]×2+a[r] l , r , 查 询 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).
操作2, 给定 x,y,使a[x]=y x , y , 使 a [ x ] = y
有 N个数据,M N 个 数 据 , M 种操作,对于每个操作1输出计算结果。
我们将要求的式子变形
这样我们可以构造并维护两个数组的树状数组,一个是a[i]的树状数组C1[i],一个是 a[i]*i的树状数组C2[i]。
注意这里是修改值而不是增加值,所以增加的是“新值与旧值得差”,并且要注意把原数组a[i]的值重新赋值。
code:
#include
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
ll a[maxn];
int n,m;
ll c1[maxn],c2[maxn];
void init(){
memset(a,0,sizeof(a));
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
}
int lowbit(int x){
return x & (-x);
}
void add1(int x,ll val){
while(x <= n){
c1[x] += val;
x += lowbit(x);
}
}
ll query1(int x){
ll ans = 0;
while(x > 0){
ans += c1[x];
x -= lowbit(x);
}
return ans;
}
void add2(int x,ll val){
while(x <= n){
c2[x] += val;
x += lowbit(x);
}
}
ll query2(int x){
ll ans = 0;
while(x > 0){
ans += c2[x];
x -= lowbit(x);
}
return ans;
}
int main(){
while(~scanf("%d%d",&n,&m)){
init();
for(int i = 1; i <= n; i++){
scanf("%lld",&a[i]);
add1(i,a[i]);
add2(i,i*a[i]);
}
ll op,l,r;
for(int i = 1; i <= m; i++){
scanf("%lld%lld%lld",&op,&l,&r);
if(op == 1)
printf("%lld\n",(r + 1) * (query1(r) - query1(l-1)) - (query2(r) - query2(l-1)));
else{
add1(l,r - a[l]);
add2(l,l * r - l * a[l]);
a[l] = r;
}
}
}
return 0;
}