poj 3468 A Simple Problem with Integers (线段树 成段更新 加值 求和)
题意:
只有这两种操作
C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
代码风格更新后:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define lson l, mid, 2*rt
#define rson mid+1, r, 2*rt+1
#define LL __int64
const int maxn = +;
using namespace std;
LL sum[*maxn], lz[*maxn]; void pushup(int rt)
{
sum[rt] = sum[*rt]+sum[*rt+];
}
void pushdown(int l, int r, int rt)
{
if(lz[rt]!=)
{
int mid = (l+r)/;
sum[*rt] += lz[rt]*(mid-l+);
sum[*rt+] += lz[rt]*(r-mid);
lz[*rt] += lz[rt];
lz[*rt+] += lz[rt];
lz[rt] = ;
}
}
void build(int l, int r, int rt)
{
if(l==r)
{
scanf("%I64d", &sum[rt]);
return;
}
int mid = (l+r)/;
build(lson);
build(rson);
pushup(rt);
}
void update(int ll, int rr, LL c, int l, int r, int rt)
{
if(ll>r) return;
if(rr<l) return;
if(ll<=l && rr>=r)
{
lz[rt] += c;
sum[rt] += (r-l+)*c;
return;
}
pushdown(l, r, rt);
int mid = (l+r)/;
update(ll, rr, c, lson);
update(ll, rr, c, rson);
pushup(rt);
}
LL query(int ll, int rr, int l, int r, int rt)
{
if(ll>r) return ;
if(rr<l) return ;
if(ll<=l && rr>=r)
return sum[rt];
pushdown(l, r, rt);
int mid = (l+r)/;
return query(ll, rr, lson)+query(ll, rr, rson);
}
int main()
{
int n, q, a, b;
LL c;
char ch;
while(~scanf("%d%d", &n, &q))
{
memset(sum, , sizeof(sum));
memset(lz, , sizeof(lz));
build(, n, );
while(q--)
{
getchar();
scanf("%c %d %d", &ch, &a, &b);
if(ch=='Q')
printf("%I64d\n", query(a, b, , n, ));
else
{
scanf("%I64d", &c);
update(a, b, c, , n, );
}
}
}
return ;
}
代码风格更新前:
分析:自己写的有点麻烦了,写的时候手残+脑残,改了好久。
val+lazy*(r-l+1)表示和,如果lazy==0表示当前区间加的值不统一。
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL __int64
const int maxn = +;
using namespace std;
int n, q;
__int64 a[maxn];
struct line
{
int l, r;
LL val, lazy;
}tr[*maxn]; void build(int o, int l, int r)
{
tr[o].l = l; tr[o].r = r;
tr[o].lazy = ;
if(l==r)
{
tr[o].val = a[l];
return;
}
int mid = (l+r)/;
build(*o, l, mid);
build(*o+, mid+, r);
tr[o].val = tr[*o].val+tr[*o+].val;
}
void update(int o, int l, int r, int add)
{
if(tr[o].l==l && tr[o].r==r)
{
tr[o].lazy += add;
return;
}
if(tr[o].lazy) //之前没向下更新的向下更新
{
tr[*o].lazy += tr[o].lazy;
tr[*o+].lazy += tr[o].lazy;
tr[o].val += (LL)(tr[o].lazy*(tr[o].r-tr[o].l+)); //同时把lazy存的加到和里
tr[o].lazy = ;
}
tr[o].val += (LL)(add*(r-l+)); //在这个过程中把新增加的加上,注意左右区间
int mid = (tr[o].l+tr[o].r)/;
if(r <= mid) update(*o, l, r, add);
else if(l > mid) update(*o+, l, r, add);
else
{
update(*o, l, mid, add);
update(*o+, mid+, r, add);
}
} LL query(int o, int l, int r)
{
if(tr[o].l==l && tr[o].r==r)
return tr[o].val + tr[o].lazy*(r-l+);
if(tr[o].lazy) //由于之前可能存在 没有更新的所以向下更新
{
tr[*o].lazy += tr[o].lazy;
tr[*o+].lazy += tr[o].lazy;
tr[o].val += (LL)(tr[o].lazy*(tr[o].r-tr[o].l+));
tr[o].lazy = ;
}
int mid = (tr[o].l+tr[o].r)/;
if(r<=mid) return query(*o, l, r);
else if(l > mid) return query(*o+, l, r);
else
{
return query(*o, l, mid) + query(*o+, mid+, r);
}
}
int main()
{
int i, l, r, add;
char ch;
while(~scanf("%d%d", &n, &q))
{
for(i = ; i <= n; i++)
scanf("%I64d", &a[i]);
build(, , n);
for(i = ; i <= q; i++)
{
getchar();
scanf("%c", &ch);
if(ch=='Q')
{
scanf("%d%d", &l, &r);
printf("%I64d\n", query(, l, r));
}
else
{
scanf("%d%d%d", &l, &r, &add);
update(, l, r, add);
}
}
}
return ;
}
poj 3468 A Simple Problem with Integers (线段树 成段更新 加值 求和)的更多相关文章
- POJ 3468 A Simple Problem with Integers (线段树成段更新)
题目链接:http://poj.org/problem?id=3468 题意就是给你一组数据,成段累加,成段查询. 很久之前做的,复习了一下成段更新,就是在单点更新基础上多了一个懒惰标记变量.upda ...
- POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...
- 【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记
A Simple Problem with Integers Time Limit:5000MS Memory Limit:131072K Case Time Limit:2000MS Descr ...
- POJ3468_A Simple Problem with Integers(线段树/成段更新)
解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio& ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和(模板)
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
- poj 3468 A Simple Problem with Integers 线段树第一次 + 讲解
A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal w ...
- [POJ] 3468 A Simple Problem with Integers [线段树区间更新求和]
A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal ...
- poj 3468 A Simple Problem with Integers (线段树区间更新求和lazy思想)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 75541 ...
随机推荐
- Core身份认证
Core中实现一个基础的身份认证 注:本文提到的代码示例下载地址> How to achieve a basic authorization in ASP.NET Core 如何在ASP.NET ...
- cocos2dx中的假动作,又称动作回调函数
1.动作与动画的区别 动作是:定时器+属性的改变,是帧循环的累积效应 动画是:帧图片的播放效果,我们知道电影的播放就是快速播放的胶片,这就是动画的原理 2.假动作:又称动作回调函数 四大类假动作: c ...
- Ubuntu下安装eclipse及PyDev插件注意事项
一.安装eclipse前一定要先安装jdk 1.到http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880 ...
- Swift Json 解析错误
昨天在开发公司的ios程序时,遇见一个json解析的问题,并且是一个非常奇怪的问题. 因为原来的代码比较复杂,所以对代码进行了一些简化,具体代码如下: 服务器返回格式(PHP): array( arr ...
- Uyuw's Concert POJ2451
裸半平面交,以前没写过,先写一遍再说 我越来越不注意细节了,最后才发现空间稍微开小了(没有开那个零头,他又要多4条边,就WA了) const maxn=; eps=1e-7; type point=r ...
- Exception in thread "http-bio-8081-exec-3" java.lang.OutOfMemoryError: PermGen space
前言: 在http://www.cnblogs.com/wql025/p/4865673.html一文中我曾描述这种异常也提供了解决方式,但效果不太理想,现在用本文的方式,效果显著. 目前此项目只能登 ...
- C# mongodb [上]
概述 MongoDB是一个高性能,开源,无模式的文档型数据库,使用C++开发.是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.他支持的数据结构非常松散,是 ...
- Matlab与微积分计算
一.极限问题的解析解 1.1 单变量函数的极限 格式1: L= limit( fun, x, x0) 格式2: L= limit( fun, x, x0, ‘left’ 或 ‘right’) > ...
- C# 中请求数据方式
#region 根据URL获取结果集 /// <summary> /// 根据URL获取结果集 默认为GET,如果数据量大了可以传入POST // ...
- jQuery插件手把手教会(二)
上次我们将到了简单的jQuery插件,这次我们继续: 面向对象的插件开发 为什么要有面向对象的思维,因为如果不这样,你可能需要一个方法的时候就去定义一个function,当需要另外一个方法的时候,再去 ...