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. 电脑开机后,就会自动运行chkdsk,我想取消chkdsk,怎么取消

     每次开机都自动检查磁盘,检测通过后下次还是一样,NTFS/FAT32分区都有可能有这样的情况,即使重装系统,仍可能出现同样情况,但是硬盘可以通过Dell 随机带的检测程序解决方法:在命令行窗口中 ...

  2. java实现在线支付

    国内电子商务系统实现的基本流程如下: 客户在系统内下订单 -> 系统根据订单生成支付宝接口url -> 客户通过url使用支付宝(网上银行)付款 -> 支付宝将客户的付款完成信息发送 ...

  3. Python中进程

    程序 程序:编写完的代码称为程序. 进程 进程:又称重量级进程,正在执行中的程序称为进程.进程的执行会占用内存等资源.多个进程同时执行时,每个进程的执行都需要由操作系统按一定的算法(RR调度.优先数调 ...

  4. 【BZOJ3932】任务查询系统(主席树)

    [BZOJ3923]任务查询系统(主席树) 题面 Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei ...

  5. Bzoj4566:[HAOI2016]找相同字符

    题面 Bzoj Sol 两个串拼在一起后求出后缀数组 然后显然的\(n^2\)暴力,就是直接枚举求\(LCP\) 又由于扫的时候是对\(height\)取\(min\) 那么可以用单调栈维护每一段的贡 ...

  6. [BZOJ1000] A+B Problem

    Description Calculate a+b Input Two integer a,b (0<=a,b<=10) Output Output a+b Sample Input 1 ...

  7. ubuntu安装Eclipse无图标(手动创建软件图标) —— 其他的软件也一样

    //退回根目录 cd / //进入图标存放目录 cd usr/share/applications/ //用文本编辑器打开打开eclipse的图标文件,没有会自动创建 sudo gedit eclip ...

  8. Vue2.0 demo:百度百聘第三方web客户端

    github地址:https://github.com/axel10/baipin_vue 项目地址:https://vcollection.org/baipin/ 官方的百度百聘客户端存在翻页时过滤 ...

  9. 基于etcd的Rabbitmq队列订阅负载均衡

    go-qb Load balancer for rabbitmq queue subscribing Feature Rabbitmq queue subscription load balancin ...

  10. kali linux安装搜狗输入法的方法

    kali linux安装搜狗输入法比较麻烦,因为有很多依赖项,不过安装好就很好用,觉得麻烦的一般安装ibus,经典,也常更新. 下面就说说怎么安装搜狗输入法: 先去http://http.kali.o ...