A Simple Problem with Integers

    题目大意:给出n个数,区间加、查询区间和。

    注释:1<=n,q<=100,000.(q为操作次数)。

      想法:嗯...学了这么长时间线段树,发现我tm竟然不会lazy标记??!好吧,看来线段树又要重新来了。

        关于这道题,主要是联系lazy标记的使用。如果每一次查询的时间复杂度都输满nlogn,那么就gg了。线段树之所以快的原因在于我们在查询到一个可以代替原来查询区间一部分的节点,我们就在这个节点上打一个lazy标记。那么我就不需要继续想该节点之后去遍历。而一个lazy标记表示这个节点的所有子节点都进行了同样的操作。那么如果我在同一个节点处打两个lazy标记,本题是区间加法,我们需要将两个lazy标记相加。我们在需要遍历的时候发现一个节点有lazy标记,我们需要将lazy标记向下推。为什么?

          因为我们打标记是为了节约时间,但是lazy标记下面的节点在当前时刻的值是没有发生更改的,所以若我们需要下面节点的值,则我就必须将上面的lazy标记向下推,就是pushdown。

          我们发现这样的话最上面的lazy标记显然是最新的。紧接着,推下lazy标记之后,我们需要将lazy标记所影响的点的值上传给father,就是pushup。

      如果最后存在一个节点,它仍然有lazy标记但是它始终没有没第二次查询或者修改,我们就节省了将lazy标记作用在它子树里的时间,这就是lazy标记节省时间的根本。

    最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson pos<<1
#define rson pos<<1|1
#define N 100010
using namespace std;
typedef long long ll;
ll lazy[4*N];
int high[N];
ll sum[4*N];
void build(int pos,int l,int r)//建树
{
int mid=(l+r)>>1;
if(l==r)
{
sum[pos]=high[l];
return;
}
build(lson,l,mid);
build(rson,mid+1,r);
sum[pos]=sum[lson]+sum[rson];//pushup
}
inline void pushdown(int pos,int l,int r)
{
if(lazy[pos])
{
int mid=(l+r)>>1;
sum[lson]+=(mid-l+1)*lazy[pos];//推标记
lazy[lson]+=lazy[pos];
sum[rson]+=(r-mid)*lazy[pos];
lazy[rson]+=lazy[pos];
lazy[pos]=0;
}
}
void fix(int pos,int l,int r,int x,int y,ll val)
{
int mid=(l+r)>>1;
if(x<=l&&r<=y)
{
lazy[pos]+=val;
sum[pos]+=(r-l+1)*val;
return;
}
pushdown(pos,l,r);
if(x<=mid)//OTZ ZTY
{
fix(lson,l,mid,x,y,val);
}
if(y>mid)//OTZ ZTY
{
fix(rson,mid+1,r,x,y,val);
}
sum[pos]=sum[lson]+sum[rson];//pushup
}
ll query(int pos,int l,int r,int x,int y)
{
int mid=(l+r)>>1;
ll temp=0;
if(x<=l&&r<=y)
{
return sum[pos];
}
pushdown(pos,l,r);
if(x<=mid)
{
temp+=query(lson,l,mid,x,y);
}
if(y>mid)
{
temp+=query(rson,mid+1,r,x,y);
}
return temp;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&high[i]);
}
build(1,1,n);
char s[10];
for(int a,b,c,i=1;i<=m;i++)
{
scanf("%s",s);
if(s[0]=='Q')
{
scanf("%d%d",&a,&b);
printf("%lld\n",query(1,1,n,a,b));
}
else
{
scanf("%d%d%d",&a,&b,&c);
fix(1,1,n,a,b,c);
}
}
return 0;
}

    小结:重新开始线段树qwq

[poj3468]A Simple Problem with Integers_线段树的更多相关文章

  1. poj3468 A Simple Problem with Integers (线段树区间最大值)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 92127   ...

  2. POJ3468 A Simple Problem with Integers(线段树延时标记)

    题目地址http://poj.org/problem?id=3468 题目大意很简单,有两个操作,一个 Q a, b 查询区间[a, b]的和 C a, b, c让区间[a, b] 的每一个数+c 第 ...

  3. poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)

    转载请注明出处:http://blog.csdn.net/u012860063 Description You have N integers, A1, A2, ... , AN. You need ...

  4. POJ3468 A Simple Problem with Integers —— 线段树 区间修改

    题目链接:https://vjudge.net/problem/POJ-3468 You have N integers, A1, A2, ... , AN. You need to deal wit ...

  5. 2018 ACMICPC上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节)

    2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节) 链接:https://ac.nowcoder.co ...

  6. poj 3468 A Simple Problem with Integers 线段树 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=3468 线段树模板 要背下此模板 线段树 #include <iostream> #include <vector> ...

  7. POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)

    A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...

  8. POJ3648 A Simple Problem with Integers(线段树之成段更新。入门题)

    A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 53169 Acc ...

  9. 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 ...

随机推荐

  1. Attribute name "aphmodel" associated with an element type "mxg" must be followed by the ' = ' charac

    1.错误描述 org.apache.batik.transcoder.TranscoderException: null Enclosed Exception: Attribute name &quo ...

  2. E: 无法获得锁 /var/lib/apt/lists/lock - open (11: 资源暂时不可用)

    1 错误描述 youhaidong@youhaidong:~$ sudo apt-get update E: 无法获得锁 /var/lib/apt/lists/lock - open (11: 资源暂 ...

  3. 双刃剑MongoDB的学习和避坑

    双刃剑MongoDB的学习和避坑 MongoDB 是一把双刃剑,它对数据结构的要求并不高.数据通过key-value的形式存储,而value的值可以是字符串,也可以是文档.所以我们在使用的过程中非常方 ...

  4. Hibernate【映射】知识要点

    前言 前面的我们使用的是一个表的操作,但我们实际的开发中不可能只使用一个表的...因此,本博文主要讲解关联映射 集合映射 需求分析:当用户购买商品,用户可能有多个地址. 数据库表 我们一般如下图一样设 ...

  5. Redis进阶实践之十五 Redis-cli命令行工具使用详解第二部分(结束)

    一.介绍           今天继续redis-cli使用的介绍,上一篇文章写了一部分,写到第9个小节,今天就来完成第二部分.话不多说,开始我们今天的讲解.如果要想看第一篇文章,地址如下:http: ...

  6. Eclipse远程debug服务器

    一,找端口号 二,Eclipse配置 三,测试是否成功 四,结束远程debug

  7. 简单使用Mysql-Cluster-7.5搭建数据库集群

    阅读目录 前言 mysql cluster中的几个概念解释 架构图及说明 下载mysql cluster 安装mysql cluster之前 安装配置管理节点 安装配置数据和mysql节点 测试 启动 ...

  8. POJO

    简单的Java对象(Plain Ordinary Java Objects)实际就是普通JavaBeans,使用POJO名称是为了避免和EJB混淆起来, 而且简称比较直接. 其中有一些属性及其gett ...

  9. C#接口--C#基础

    1.接口的声明 接口:描述属于任何类或者结构的一组相关功能,是一种规范.功能 组成:属性.方法.事件.索引或者这四种成员的任意组合构成 基本知识点: 1)接口默认的权限修饰符是:public,不允许加 ...

  10. 【BZOJ2333】棘手的操作(左偏树,STL)

    [BZOJ2333]棘手的操作(左偏树,STL) 题面 BZOJ上看把... 题解 正如这题的题号 我只能\(2333\) 神TM棘手的题目... 前面的单点/联通块操作 很显然是一个左偏树+标记 ( ...