返回

ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn't want to study(树状数组)

发布时间:2022-11-04 11:07:01 204
# c++

​​ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn’t want to study​​

题目

给一个 1e5 序列,有 1e5 次操作,每次操作有两种,1 单点修改,2 查询区间 (l, r) 值,
每个区间 【l, r】值计算过程(L 为区间长度):

一个是普通前缀和,另一个是题目中的 1 ~ n 前缀和。

求区间 【l, r】就是图中梯形减去平行四边形,也就是减去一定倍数的普通区间和。

用树状数组维护前缀和。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const int N = 1e5 + 10;
const int M = 1e2 + 5;

int n, q;
ll c1[N], c2[N], a[N];

void upd(int x, ll val){
ll t = val * (n-x+1);
while(x <= n){
c1[x] += val; // 普通前缀和
c2[x] += t; // 题目前缀和
x += (x&-x);
}
}
ll sum1(int x){
ll res = 0;
while(x > 0){
res += c1[x];
x -= (x&-x);
}
return res;
}
ll sum2(int x){
ll res = 0;
while(x > 0){
res += c2[x];
x -= (x&-x);
}
return res;
}

int main(){
scanf("%d%d", &n, &q);
for(int i = 1; i <= n; i++){
scanf("%lld", &a[i]);
upd(i, a[i]);
}
while(q--){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
if(x == 1){
ll ans1 = sum1(z) - sum1(y-1);
ll ans2 = sum2(z) - sum2(y-1);
printf("%lld\n", ans2 - ans1 * (n - z));
}else{
ll t = z - a[y]; // 增量
a[y] = z;
upd(y, t);
}
}
return 0;
}
/*
*/

 

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线