POJ 3468 A Simple Problem with Integers (线段树成段更新)

时间:2023-12-28 21:38:26

题目链接:http://poj.org/problem?id=3468

题意就是给你一组数据,成段累加,成段查询。

很久之前做的,复习了一下成段更新,就是在单点更新基础上多了一个懒惰标记变量。updata的时候刚好在(l==T[p].l && r==T[p].r)的时候不更新下去,暂时用一个懒惰变量存了起来(所以才懒惰),不然继续更新下去复杂度会很高。在query的时候更新到下一层(看代码,多打打就有体会了)。

 #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1e5 + ;
typedef long long LL;
struct segtree {
int l , r;
LL add , sum;
}T[MAXN << ]; void init(int p , int l , int r) {
T[p].add = , T[p].l = l , T[p].r = r;
int mid = (l + r) >> ;
if(l == r) {
scanf("%lld" , &T[p].sum);
return ;
}
init(p << , l , mid);
init((p << )| , mid + , r);
T[p].sum = T[p << ].sum + T[(p << )|].sum;
} void updata(int p , int l , int r , int val) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == l && T[p].r == r) {
T[p].add += val;
return ;
}
T[p].sum += val * (r - l + );
if(r <= mid) {
updata(p << , l , r , val);
}
else if(l > mid) {
updata((p << )| , l , r , val);
}
else {
updata(p << , l , mid , val);
updata((p << )| , mid + , r , val);
}
} LL query(int p , int l , int r) {
int mid = (T[p].l + T[p].r) >> ;
if(l == T[p].l && T[p].r == r) {
return T[p].sum + T[p].add * (r - l + );
}
if(T[p].add) {
T[p].sum += T[p].add * (T[p].r - T[p].l + );
T[p << ].add += T[p].add;
T[(p << )|].add += T[p].add;
T[p].add = ;
}
if(r <= mid) {
return query(p << , l , r);
}
else if(l > mid) {
return query((p << )| , l , r);
}
else {
return query(p << , l , mid) + query((p << )| , mid + , r);
}
} int main()
{
char str[];
int n , m , x , y , z;
while(~scanf("%d %d" , &n , &m)) {
init( , , n);
while(m--) {
scanf("%s" , str);
if(str[] == 'Q') {
scanf("%d %d" , &x , &y);
printf("%lld\n" , query( , x , y));
}
else {
scanf("%d %d %d" , &x , &y , &z);
updata( , x , y , (LL)z);
}
}
}
}