POJ 3468 A Simple Problem with Integers:
http://poj.org/problem?id=3468
区间更新 和 区间求和
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define sf scanf
#define pf printf
using namespace std;
const int maxn = 100000 + 5;
typedef long long LL;
struct Node{
LL v,mark;
}Nodes[maxn * 4];
int A[maxn];
LL Build(int cur,int l,int r){ //建树
Nodes[cur].mark = 0;
if(l == r){
return Nodes[cur].v = A[l];
}
int m = (r + l) / 2;
return Nodes[cur].v = Build(cur * 2,l,m) + Build(cur * 2 + 1,m + 1,r);
}
void Maintian(int cur,int l,int r){ //向下推延迟标记
if(Nodes[cur].mark){ //如果当前节点有延迟标记
//更新孩子节点的值
int m = (l + r) / 2;
Nodes[cur * 2].v += Nodes[cur].mark * (m - l + 1);
Nodes[cur * 2 + 1].v += Nodes[cur].mark * (r - m);
//延迟标记标记至孩子节点
Nodes[cur * 2].mark += Nodes[cur].mark;
Nodes[cur * 2 + 1].mark += Nodes[cur].mark;
//当前节点延迟标记清空
Nodes[cur].mark = 0;
}
}
LL Query(int cur,int l,int r,int cl,int cr){ //查询
if(cr < l || cl > r) return 0; //如果当前区间内 不包含查询区间 则返回0
if(cl == cr){ //区间长度为1 返回节点值
return Nodes[cur].v;
}
if(l <= cl && r >= cr){ //当前区间完全包含在查询区间内
return Nodes[cur].v;
}
Maintian(cur,cl,cr); //需要向下查询孩子节点的时候 将当前节点的延迟标记向下推送
int m = (cl + cr) / 2;
return Query(cur * 2,l,r,cl,m) + Query(cur * 2 + 1,l,r,m + 1,cr);
}
LL Update(int cur,int l,int r,int cl,int cr,LL mark){ //更新区间 返回修改后的区间和
if(cl > r || cr < l) return Nodes[cur].v; //当前区间与更新区间没有交集 不修改当前区间值 直接返回原来的值
if(cl == cr){ //当前区间为1 修改节点值
Nodes[cur].v += mark;
return Nodes[cur].v;
}
if(l <= cl && r >= cr){ //当前区间完全包含在修改区间内
Nodes[cur].v += (cr - cl + 1) * mark; //修改区间值
Nodes[cur].mark += mark; //更新延迟标记
return Nodes[cur].v; //返回区间修改值
}
Maintian(cur,cl,cr); //需要向下更新孩子节点 则将延迟标记向下推送
int m = (cl + cr) / 2;
Nodes[cur].v = Update(cur * 2,l,r,cl,m,mark) + //当前节点的值 等于 孩子节点更新后的值得和
Update(cur * 2 + 1,l,r,m + 1,cr,mark);
return Nodes[cur].v;
}
int main(){
int T,x,y,z;
char op;
int n,m;
while( ~sf("%d %d",&n,&m) ){
for(int i = 1;i <= n;++i) sf("%d",&A[i]);getchar();
Build(1,1,n);
for(int i = 0;i < m;++i){
sf("%c %d %d",&op,&x,&y);
// pf("op = %c\n",op);
if(op == 'C'){
sf("%d",&z);
Update(1,x,y,1,n,z);
}
else{
pf("%lld\n",Query(1,x,y,1,n));
}
getchar();
}
}
return 0;
}