PKU 3468
A Simple Problem with Integers
题型:线段树,区间的修改+区间统计
描述:1~n个数,[a,b]区间内的每个数加上C,询问区间[a,b]的数字和。
思路:用两个域:v, add来维护,v为区间和,add为区间增量。区间的修改过程,回溯时增加了对父节点v域的修改;区间的统计过程,需要将父节点的增量add域计算进去。
struct Seg {
int l, r, md;
__int64 add;
__int64 v;
}t[NL*2];
区间的修改
void mody(int l, int r, int c, int k)
{
if (t[k].l == l && t[k].r == r){
t[k].add += c;
t[k].v += (r-l)*c;
return;
}
if (r <= t[k].md)
mody(l, r, c, 2*k);
else if (l >= t[k].md)
mody(l, r, c, 2*k+1);
else {
mody(l, t[k].md, c, 2*k);
mody(t[k].md, r, c, 2*k+1);
}
t[k].v += (r-l)*c;
}
区间的统计
__int64 count(int l, int r, int k)
{
if (t[k].l == l && t[k].r == r) {
return t[k].v;
}
__int64 p = (r-l)*t[k].add;
if (r <= t[k].md)
return count(l, r, 2*k) + p;
else if (l >= t[k].md)
return count(l, r, 2*k+1) + p;
else
return count(l, t[k].md, 2*k) + count(t[k].md, r, 2*k+1) + p;
}