【成端更新线段树模板】POJ3468-A Simple Problem with Integers
http://poj.org/problem?id=3468
_(:зゝ∠)_我又活着回来啦,前段时间太忙了写的题没时间扔上来,以后再说。
【问题描述】
成段加某一个值,然后询问区间和。
【思路】
讲一下pushdown和pushup出现的几个位置。
pushup:
(1)build的结尾,当叶子节点分别有对应的值后,它的父亲们就等于它们求和。
(2)update的结尾,因为此时当前根的左右孩子已经更新了,故它也需要更新。
pushdown(延迟标记):
*pushdown会出现在一切要从当前结点往下的位置
query和update中,要先把add的值传给两个儿子。
接下来整理一下思路,每一个子过程分别需要如何操作:
build(建立线段树)
(1)将add清零
(2)如果左子树等于右子树,则说明已经到达叶子节点,读入sum的值,返回
(3)向左右子树递归
(4)pushup更新当前根
update(修改)
(1)如果当前的L和R包含在l和r中,则让add+δ,让sum+δ*当前区间的长度,返回
(2)pushdown向下延迟标记
(3)向左右子树递归
(4)pushup更新当前根
query(查询)
(1)如果当前的L和R包含在l和r中,则直接返回sum[rt]
(2)pushdown向下延迟标记
(3)向左右子树递归,将得到的返回值加到result总
(4)返回result
一般的线段树就是这样操作的,其实还挺简单(。・∀・)ノ゙最近学业有点忙好久没写程序了,整理一个当作恢复一下手速。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
const int MAXN=+;
int n,q;
LL add[MAXN];
LL sum[MAXN]; void pushup(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];
} void build(int l,int r,int rt)
{
add[rt]=;
if (l==r)
{
scanf("%lld",&sum[rt]);
return;
}
int m=(l+r)/;
build(lson);
build(rson);
pushup(rt);
} void pushdown(int rt,int m)
{
if (add[rt])
{
add[rt<<]+=add[rt];
add[rt<<|]+=add[rt];
sum[rt<<]+=add[rt]*(m-(m>>));
sum[rt<<|]+=add[rt]*(m>>);
add[rt]=;
}
} LL query(int L,int R,int l,int r,int rt)
{
if (L<=l && R>=r)
{
return sum[rt];
}
pushdown(rt,r-l+);
int m=(l+r)/;
LL rs=;
if (m>=L) rs+=query(L,R,lson);
if (m<R) rs+=query(L,R,rson);
return rs;
} void update(int L,int R,int delta,int l,int r,int rt)
{
if (L<=l && R>=r)
{
add[rt]+=delta;
sum[rt]+=(LL)delta*(r-l+);
return;
}
pushdown(rt,r-l+);
int m=(l+r)/;
if (m>=L) update(L,R,delta,lson);
if (m<R) update(L,R,delta,rson);
pushup(rt);
} int main()
{
scanf("%d%d",&n,&q);
build(,n,);
for (int i=;i<q;i++)
{
char c[];
scanf("%s",c);
if (c[]=='C')
{
int fr,ed,ad;
scanf("%d%d%d",&fr,&ed,&ad);
update(fr,ed,ad,,n,);
}
else
{
int a,b;
scanf("%d%d",&a,&b);
cout<<query(a,b,,n,)<<endl;
}
}
return ;
}
【成端更新线段树模板】POJ3468-A Simple Problem with Integers的更多相关文章
- 线段树专题 POJ3468 A Simple Problem with Integers
题意:n个点.m个操作.两种操作类型.C X Y K 表示区间[x,y]上每一个点值加k.Q X Y 求区间[x,y]的和 分析:线段树区间求和,裸模板 注意:结果会超int,要用long long ...
- (线段树模板)A Simple Problem with Integers --POJ--3468
链接: http://poj.org/problem?id=3468 代码: #include<stdio.h> #include<algorithm> #include< ...
- POJ 3468 (线段树 区间增减) A Simple Problem with Integers
这题WA了好久,一直以为是lld和I64d的问题,后来发现是自己的pushdown函数写错了,说到底还是因为自己对线段树理解得不好. 因为是懒惰标记,所以只有在区间分开的时候才会将标记往下传递.更新和 ...
- 线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和
poj3468 A Simple Problem with Integers 题意:O(-1) 思路:O(-1) 线段树功能:update:成段增减 query:区间求和 Sample Input 1 ...
- POJ3468 A Simple Problem with Integers 【段树】+【成段更新】
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 57666 ...
- poj3468 A Simple Problem with Integers (线段树区间最大值)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 92127 ...
- poj3468 A Simple Problem with Integers(zkw区间修改模板)
此题是一道线段树的裸题,这里只是为了保存我的zkw线段树模板 #include <cstdio> #include <cstring> #include <iostrea ...
- poj3468 A Simple Problem with Integers (树状数组做法)
题目传送门 A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 1 ...
- poj------(3468)A Simple Problem with Integers(区间更新)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 60745 ...
随机推荐
- C# 文件类的操作---删除
//删除文件夹 1这是最简单的方法 DirectoryInfo di = new DirectoryInfo(string Path); di.Delete(true); 注:path是你要删除的非空 ...
- mssql手工注入2
--+ 先说一些函数的说明: substring(str,start,len) 截取字符串的作用,第一个参数为要截取的字符串,第二个参数为从哪里开始截取,第三个参数为截取的长度 ascii(char) ...
- 以下suse11.3x64可以安装pycrypto-2.6.1
rpm -qa adaptec-firmware-1.35-2.15.4gnome-menus-branding-SLED-11.1-14.26man-pages-3.15-2.23.1crackli ...
- 【转】CVE-2010-4258 漏洞分析
一. 漏洞简介 CVE-2010-4258这个漏洞很有意思,主要思路是如果通过clone函数去创建进程,并且带有CLONE_CHILD_CLEARTID标志,那么进程在退出的时候,可以造成内核任意地址 ...
- 网络知识===wireshark抓包,三次握手分析
TCP需要三次握手建立连接: 网上的三次握手讲解的太复杂抽象,尝试着使用wireshark抓包分析,得到如下数据: 整个过程分析如下: step1 client给server发送:[SYN] Seq ...
- Shell脚本中引用、调用另一个脚本文件的2种方法
Shell脚本中引用.调用另一个脚本文件的2种方法 http://www.jb51.net/article/67903.htm
- Lambda 表达式 in java 8
Lambda 表达式 in Java 8 Lambda表达式是java 8 新增的特性 Lambda表达式主要作用:支持将代码块作为方法参数,允许使用更简洁的代码创建函数式接口的实例,是匿名内部类的一 ...
- ==和equals()方法的区别
==和equals()方法的区别 这是一道经典的面试题,但是很多人对其一直很困惑,最近刚好复习了他们两者的区别,现总结如下: 一.==:两端可以存放不同的数据 1.放基本数据类型:根据基本数据 ...
- Go语言大神亲述:历七劫方可成为程序员!
“历劫1”:你坚信你可以用Go来做面向对象编程? 在经历了一次Go应用之旅之后,你可能就会开始思考:“怎么样才能让这种语言更像面向对象的编程语言?”因为你已经习惯了这种编程,你想要制作健壮的代码.想要 ...
- SQL 分页通用存储过程
USE [DB] GO /****** Object: StoredProcedure [dbo].[SP_AspNetPager] Script Date: 10/23/2015 16:37:33 ...