您的位置:首页 > 其它

poj3468 A Simple Problem with Integers(成段更新)

2016-05-15 21:57 316 查看
http://poj.org/problem?id=3468

题意:给你n个数q个操作,q查询,c为某一段内的值增加一定的增幅。

思路:本来想自己敲出lazy,失败了。。看了别人的,增加add域,在查询和更新区间内每次判断该节点是否有增量。若有,则说明递归到了此节点,但不是所求的区间,也就没有价值了,将价值传递给儿子节点,add和sum同时更新。这里sum求和时,每次都是在原有的基础上增加增量*节点数。其余感觉也没什么,但为毛自己就是敲不出来。。。

#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <iostream>

using namespace std;

const int N = 100010;
const int INF = 1e8;

struct line//线段树节点
{
int l, r;//左右端点
__int64 sum;//节点总和
__int64 add;//增量
}tree[4*N];

__int64 a0
;

void build(int i, int l, int r)
{
tree[i].l = l;
tree[i].r = r;
tree[i].add = 0;
if(l == r)
{
tree[i].sum = a0[l];
return;
}
int mid = (l+r) >> 1;
build(i*2, l, mid);
build(i*2+1, mid+1, r);
tree[i].sum = tree[i*2].sum+tree[i*2+1].sum;
}

void update(int i, int l, int r, __int64 add)
{
tree[i].sum += (r-(l-1))*add;
if(tree[i].l == l && tree[i].r == r)
{
tree[i].add += add;
return;
}
if(tree[i].add)
{
tree[i*2].add += tree[i].add;
tree[i*2+1].add += tree[i].add;
tree[i*2].sum += tree[i].add*(tree[i*2].r-(tree[i*2].l-1));
tree[i*2+1].sum += tree[i].add*(tree[i*2+1].r-(tree[i*2+1].l-1));
tree[i].add = 0;
}
int mid = (tree[i].l+tree[i].r) >> 1;
if(mid >= r)
update(i*2, l, r, add);
else if(mid < l)
update(i*2+1, l, r, add);
else
{
update(i*2, l, mid, add);
update(i*2+1, mid+1, r, add);
}
}

__int64 query(int i, int l, int r)
{
if(tree[i].l == l && tree[i].r == r)
{
return tree[i].sum;
}
if(tree[i].add)
{
tree[i*2].add += tree[i].add;
tree[i*2+1].add += tree[i].add;
tree[i*2].sum += tree[i].add*(tree[i*2].r-(tree[i*2].l-1));
tree[i*2+1].sum += tree[i].add*(tree[i*2+1].r-(tree[i*2+1].l-1));
tree[i].add = 0;
}
int mid = (tree[i].l+tree[i].r) >> 1;
if(mid >= r)
return query(i*2, l, r);
else if(mid < l)
return query(i*2+1, l, r);
else
{
return query(i*2, l, mid)+query(i*2+1, mid+1, r);
}
}

int main()
{
//  freopen("in.txt", "r", stdin);
int n, q, a, b;
__int64 c;
char s[5];
scanf("%d%d", &n, &q);
for(int i = 1; i <= n; i++)
{
scanf("%I64d", &a0[i]);
}
build(1, 1, n);
for(int i = 1; i <= q; i++)
{
scanf("%s", s);
if(s[0] == 'Q')
{
scanf("%d%d", &a, &b);
printf("%I64d\n", query(1, a, b));
}
else if(s[0] == 'C')
{
scanf("%d%d%I64d", &a, &b, &c);
update(1, a, b, c);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj