hdu1698 Just a Hook 【区间修改】(模板题)
<题目链接>
题目大意:
一段线段由n条小线段组成,每次操作把一个区间的小线段变成金银铜之一(金的价值为3,银为2,铜为1),最初可当做全为铜;最后求这条线段的总价值。
解题分析:
此题为线段树区间修改的一道模板题,区间修改的重点就是懒惰标记,即线面代码中的 lazy[]数组,因为我们主要想求的是某一区间的总和,而对该区间内每一个离散点的具体值没有兴趣,所以,当我们进行区间修改的时候,只需要修改该区间所对应节点的值,同时用懒惰标记记录(我认为懒惰标记实际上是指该节点的所有子节点的实际值)。如果题目没有要求访问到或者更新到这些子节点的话,我们就可以省下许多步骤,不用将每一次操作的区间内的每一个离散点(对应的叶子节点以及对应路径上的所有节点的值全部更新)。具体实现见代码。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = + ;
int lazy[maxn << ], sum[maxn << ]; void PushUp(int rt) { sum[rt] = sum[rt << ] + sum[rt << | ]; } void pushdown(int rt, int len) //将懒惰标记传递给该节点的左右儿子,同时更新该节点左右儿子的sum值(对应区间总值)
{
if (lazy[rt]) //如果lazy不是0,则说明该区间被修改过
{
lazy[rt << ] = lazy[rt];
lazy[rt << | ] = lazy[rt];
sum[rt << ] = lazy[rt] * (len - (len >> )); //注意这种求左儿子区间长度的方法,因为左儿子包含了mid,所以可以这样求 (len-(len>>1))
sum[rt << | ] = lazy[rt] * (len >> );
lazy[rt] = ; //该节点的lazy重新置0
}
} void build(int rt, int l, int r)
{
lazy[rt] = ;
if (l == r)
{
sum[rt] = ; //初始为铜,值为1
return;
}
int mid = (l + r) >> ;
build(rt << , l, mid);
build(rt << | , mid + , r);
PushUp(rt);
} void update(int L, int R, int c, int l, int r, int rt)
{
if (L<=l&&r<=R)
{
lazy[rt] = c;
sum[rt] = c * (r - l + ); //从这里可以看出,lazy[]是对该节点以下的所有子节点起作用的,该节点的sum为对应区间总和的实际值,而它的子节点的sum的实际值则取决于lazy
return;
}
pushdown(rt, r - l + ); //如果上面的if语句不成立(未找到要求区间),所以要继续向该节点的左右儿子查询,所以要将该节点的lazy标记下放给该节点的左右儿子
int mid = (l + r) >> ;
if (L <= mid)update(L, R, c, l, mid, rt << );
if (R > mid)update(L, R, c, mid + , r, rt << | );
PushUp(rt); //懒惰标记只能保证递归到该要求的区间时停止,所以依然要更新包含该段区间的所有大区间的值
} int query(int L, int R, int l, int r, int rt)
{
if (L <= l && r <= R)
{
return sum[rt];
}
pushdown(rt, r - l + );
int mid = (l + r) >> ;
int ans = ;
if (L <= mid)ans += query(L, R, l, mid, rt << ); //在该节点左儿子的值
if (R > mid)ans += query(L, R, mid + , r, rt << | );
return ans;
} int main()
{
int t; cin >> t;
for(int ncase = ; ncase <= t;ncase++)
{
int n; scanf("%d", &n);
int m; scanf("%d", &m);
build(, , n);
for (int i = ; i < m; i++)
{
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
update(x, y, z, , n, );
}
printf("Case %d: The total value of the hook is %d.\n", ncase, query(, n, , n, ));
}
return ;
}
2018-07-24
hdu1698 Just a Hook 【区间修改】(模板题)的更多相关文章
- 线段树:Segment Tree(单点修改/区间修改模板) C++
线段树是非常有效的数据结构,可以快速的维护单点修改,区域修改,查询最大值,最小值等功能. 同时,它也很重要.如果有一天比赛,你卡在了一道线段树模板题目上,这就真的尴尬了.不过,随着时代的进步,题目也越 ...
- BZOJ 3223: Tyvj 1729 文艺平衡树-Splay树(区间翻转)模板题
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 6881 Solved: 4213[Submit][Sta ...
- POJ - 3468 线段树单点查询,单点修改区间查询,区间修改模板(求和)
题意: 给定一个数字n,表示这段区间的总长度.然后输入n个数,然后输入q,然后输入a,b,表示查询a,b,区间和,或者输入c 再输入三个数字a,b,c,更改a,b区间为c 思路: 线段树首先就是递归建 ...
- poj3468 A Simple Problem with Integers(zkw区间修改模板)
此题是一道线段树的裸题,这里只是为了保存我的zkw线段树模板 #include <cstdio> #include <cstring> #include <iostrea ...
- HDU1698 Just a Hook (区间更新)
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 石子合并 区间DP模板题
题目链接:https://vjudge.net/problem/51Nod-1021 题意 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石 ...
- P4145——线段树点修改&&模板题
题目 链接 题意:对一个数列进行以下两种操作: 给$[l,r]$中的每个数开平方(下取整) 询问$[l,r]$中各个数的和 解决方法 显然,区间开平方不满足区间可加性,所以对区间中每个数开平方不能通过 ...
- A - Brackets POJ - 2955 (区间DP模板题)
题目链接:https://cn.vjudge.net/contest/276243#problem/A 题目大意:给你一个字符串,让你求出字符串的最长匹配子串. 具体思路:三个for循环暴力,对于一个 ...
- FZU Problem 2171 防守阵地 II (线段树区间更新模板题)
http://acm.fzu.edu.cn/problem.php?pid=2171 成段增减,区间求和.add累加更新的次数. #include <iostream> #include ...
- P1198最大数——线段树点修改&&模板题
题目 题目链接 大意:维护一个数列,有两种操作: 查询操作Q L:查询当前数列中末尾L个数中的最大的数 插入操作A n:将n加上t再对D取模,将所得值插入数列末尾 解决方案 由题意知,只有两种操作 ...
随机推荐
- Builder建造者模式
- 修改weblogic的端口
两种方法可以修改,第一种方法是后台管理界面修改,第二种是配置文件修改,下面分别介绍: 1.后台修改 (1)进入weblogic登陆界面:(默认端口是7001) (2)登陆之后点击服务器----然后管理 ...
- springMVC入门(一)
1. SpringMVC入门 1.1SpringMVC是什么 Spring web mvc和Struts2都属于表现层的框架,它是Spring框架的一部分,我们可以从Spring的整体结构中看得出 ...
- linux 命令格式
1.命令 选项 参数 选项——短选项: - 多个选项可以合在一起书写 ——长选项:-- 选项是一个word 参数:命令的作用对象 ls -la /etc /opt 2.su swit ...
- pl/sql Devloper 快捷键__新建sql窗口
首先,打开PLSQL,菜单栏--->首选项----->键配置 其次,点击你要增加快捷键的选项,直接键盘上输入快捷键: 比如你要修改为CTRL+N,直接在键盘上按出CTRL+N即可. ESC ...
- Pcap4J实现抓包器
前段时间搞抓包程序,打算使用Pcap4J实现,发现除了GitHub,其它资料少之又少,几乎都是不起作用. 被迫我一直看(日本作者!)英文注解的源码和sample和test,比较费劲+营养很少.因为几乎 ...
- awk对列/行进行统计求和【转】
场景]--类似于excel中的sum函数对列/行进行统计求和 A01 A02 A03 A09 [要求1]--对列进行统计求和 A01 A02 A03 A09 TOTAL [要求2]--对行进行统计求和 ...
- python标准库之secrets
secrets secrets是python3.6加入到标准库的,使用secrets模块,可以生成适用于处理机密信息(如密码,帐户身份验证,安全令牌)的加密强随机数. 导入 import secret ...
- centos7.2环境编译安装mysql5.5.48
一.安装cmake编译工具 跨平台编译器 查看是否已经安装了gcc # rpm -qa | grep gcc # yum install -y gcc-c++ # yum install -y cma ...
- js常用函数整理
类型转换:parseInt\parseFloat\toString 类型判断:typeof;eg:if(typeof(var)!="undefined")\isNaN 字符处理函数 ...