2018icpc徐州网络赛-H Ryuji doesn't want to study(线段树)

时间:2023-03-10 01:32:55
2018icpc徐州网络赛-H Ryuji doesn't want to study(线段树)

题意:

有n个数的一个数组a,有两个操作:

1 l r:查询区间[l,r]内$a[l]*(r-l+1)+a[l+1]*(r-l)+a[l+2]*(r-l-1)+\cdots+a[r-1]*2+a[r]$

2 l r:将a[l]修改为r

n<=1e5,  a[i]<=1e9

思路:

预处理出前缀和s[i], 则操作1变为查询$s[l]+s[l+1]+..+s[r]-(r-l+1)*s[l-1]$

为防止爆ll(其实也不会爆的)可以在查询操作力就提前减去s[l-1]

坑点来了。。操作2即区间s(l,n)加上r-a[l],由于我们线段树里的一些标记操作,实际上a[i]和s[i]数组并没有变!

所以我们每次需要用s或a数组的时候都要query。。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 1e6+;
const int maxm = 2e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);
ll sum[maxn<<];
ll s[maxn];
ll a[maxn];
int ii;
void build(int l, int r, int root){
int mid = l + ((r - l) >> );//位运算TMD优先级!
if(l == r){
sum[root] = s[l];
return;
}
build(lson);
build(rson);
sum[root] = sum[lc]+sum[rc];
} ll addv[maxn << ];
//将root的信息传到左右节点上
void pushup(int root){
sum[root] = sum[lc] + sum[rc];
return;
}
void pushdown(int l, int r, int root){
if(addv[root]){
addv[lc] += addv[root];
addv[rc] += addv[root];
int mid = l + ((r-l)>>);
sum[lc] += addv[root]*(mid-l+);
sum[rc] += addv[root]*(r-mid);
addv[root] = ;
}
return;
}
void update(int ql, int qr, ll add, int l, int r, int root){
if(ql <= l && qr >= r){
addv[root] += add;
sum[root] += add*(r-l+);
return;
}
pushdown(l, r, root);
int mid = l + ((r-l)>>);
if(ql <= mid) update(ql, qr, add, lson);
if(qr > mid) update(ql, qr, add, rson);
pushup(root);
return;
}
ll query(int ql, int qr, int l, int r, int root){
if(ql==)return ;
if(ql <= l && qr >= r) return sum[root];//(sum[root]-(ll)((ll)r-l+1)*s[ii-1]);
pushdown(l, r, root);
int mid = l + ((r-l)>>);
ll ans = ;
if(ql <= mid) ans += query(ql, qr, lson);
if(qr > mid) ans += query(ql, qr, rson);
return ans;
}
int main() {
int n, q;
scanf("%d %d", &n, &q);
for(int i =; i <= n ; i++){
scanf("%lld", &a[i]);
}s[] = ;
mem(s, );
for(int i = ; i <= n; i++){
s[i] = a[i]+s[i-];
}
mem(addv, );
mem(sum, );
build(, n, );
while(q--){
int c,l,r;
scanf("%d %d %d", &c, &l, &r);
if(c==){
ii = l;
printf("%lld\n", query(l, r, , n, ) -(r-l+)*query(l-,l-,,n,));
}
else if(c==){
ll tmp = (ll)r-(query(l, l, , n, ) -query(l-, l-, , n, ));
update(l, n, tmp, , n, );
}A
}
return ;
}
/*
5 10
1000000000 1000000000 1000000000 1000000000 1000000000
1 2 4
2 1 0
1 2 4
*/