HDU 1698 Just a Hook(线段树/区间更新)
题目链接: 传送门
Minimum Inversion Number
Time Limit: 1000MS Memory Limit: 32768 K
Description
In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is made up of several consecutive metallic sticks which are of the same length.
Now Pudge wants to do some operations on the hook.
Let us number the consecutive metallic sticks of the hook from 1 to N. For each operation, Pudge can change the consecutive metallic sticks, numbered from X to Y, into cupreous sticks, silver sticks or golden sticks.
The total value of the hook is calculated as the sum of values of N metallic sticks. More precisely, the value for each kind of stick is calculated as follows:
For each cupreous stick, the value is 1.
For each silver stick, the value is 2.
For each golden stick, the value is 3.
Pudge wants to know the total value of the hook after performing the operations.
You may consider the original hook is made up of cupreous sticks.
Input
The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 10 cases.
For each case, the first line contains an integer N, 1<=N<=100,000, which is the number of the sticks of Pudge’s meat hook and the second line contains an integer Q, 0<=Q<=100,000, which is the number of the operations.
Next Q lines, each line contains three integers X, Y, 1<=X<=Y<=N, Z, 1<=Z<=3, which defines an operation: change the sticks numbered from X to Y into the metal kind Z, where Z=1 represents the cupreous kind, Z=2 represents the silver kind and Z=3 represents the golden kind.
Output
For each case, print a number in a line representing the total value of the hook after the operations. Use the format in the example.
Sample Iutput
1
10
2
1 5 2
5 9 3
Sample Output
Case 1: The total value of the hook is 24.
解题思路
肯定不能用单点更新的办法来逐个更新一个区间,而正解的区间更新一开始也看得我云里雾里,最好的办法就是跟着程序走一遍,调试一遍。
懒惰标记是整个代码的核心,搞懂了懒惰标记也就理解了整个算法。懒惰标记实际上就是让叶子节点暂时处于不更新状态,用到的时候再更新,代码中我用col[]数组用来作为懒惰标记,假设区间总长度是1-10,我们现在想要更新1-6,(将1-6的值都加3)那么update()会先找1-10,发现不合适,再找他的左右孩子,发现1<5,说明1-6的区间在1-10的左孩子中,同时6>5,1-6也在1-10的右孩子中,这样依次去找1-6在的区间。但是找到1-5的时候,我们发现整个1-5都在1-6中间,也就是说这一段都要更新,那么我们将1-5的sum值更新了,同时用col[rt]+=3记录下来1-5中的数字现在每个都要加的数字,但是1-5下边还有1-3,4-5,3-3,4-4,5-5,这些我们就可以不用更新,因为这些我们暂时还用不到,假如现在又要将1-5区间的值都加5,那么col[rt]+=5,此时就是8了,但是还是不用更新他的子节点,假如我们现在要用到1-3区间了,我们就可以一次性给1-3区间加上8,而不用先加3,再加5,这样懒惰标记就使得每次的递归都少了好多。
以上图为例,我先更新[5-7]区间的数为3,此时程序跑完之后会将sum[3] = 3(sum数组下标即为叶子结点),而节点3之后的叶子节点暂不更新,之后我又更新了[4-7]区间的数为2,程序跑一遍,将sum[3] = 2(叶子节点不再往下更新),sum[11] = 2,最后我更新了[5-6]区间的数为1,因为区间[5-6]包含在区间[5-7]里面,所以程序往[5-7]这个大节点跑下去,节点3之前打过懒惰标记,此时程序将更新之前在[5-7]区间未更新的叶子节点,按照完全二叉树建立的特点很容易明白sum[rt<<1] = (m - (m >> 1)) * col[rt];sum[rt<<1|1] = (m >> 1) * col[rt];这两句代码中col[rt]前面的系数为什么如此写。如果程序最后更新的是[4-6]区间,那么程序出了跑[5-7]这个大区间之外,额外跑一个节点11.
#include<cstdio>
#include<algorithm>
using namespace std;
#define lson l ,m ,rt << 1
#define rson m + 1 ,r , rt << 1 | 1
const int maxn = 100005;
int sum[maxn<<2],col[maxn<<2];
void PushUp(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushDown(int rt,int m)
{
if (col[rt])
{
col[rt<<1] = col[rt<<1|1] = col[rt];
sum[rt<<1] = (m - (m >> 1)) * col[rt];
sum[rt<<1|1] = (m >> 1) * col[rt];
col[rt] = 0;
}
}
void build(int l,int r,int rt)
{
col[rt] = 0;
sum[rt] = 1;
if (l == r) return;
int m = (l + r) >> 1;
build(lson);
build(rson);
}
void upd(int L,int R,int c,int l,int r,int rt)
{
if (L <= l && r <= R)
{
col[rt] = c;
sum[rt] = (r - l + 1) * c;
return;
}
PushDown(rt,r - l + 1);
int m = (l + r) >> 1;
if (L <= m) upd(L,R,c,lson);
if (R > m) upd(L,R,c,rson);
PushUp(rt);
}
int main()
{
int T;
scanf("%d",&T);
for (int i =1;i <= T;i++)
{
int n,m,x,y,z;
scanf("%d%d",&n,&m);
build(1,n,1);
while (m--)
{
scanf("%d%d%d",&x,&y,&z);
upd(x,y,z,1,n,1);
}
printf("Case %d: The total value of the hook is %d.\n",i,sum[1]);
}
return 0;
}
HDU 1698 Just a Hook(线段树/区间更新)的更多相关文章
- (简单) HDU 1698 Just a Hook , 线段树+区间更新。
Description: In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of ...
- HDU 1698 Just a Hook(线段树区间更新查询)
描述 In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes ...
- HDU 1698 Just a Hook 线段树区间更新、
来谈谈自己对延迟标记(lazy标记)的理解吧. lazy标记的主要作用是尽可能的降低时间复杂度. 这样说吧. 如果你不用lazy标记,那么你对于一个区间更新的话是要对其所有的子区间都更新一次,但如果用 ...
- HDU 1698 Just a Hook(线段树 区间替换)
Just a Hook [题目链接]Just a Hook [题目类型]线段树 区间替换 &题解: 线段树 区间替换 和区间求和 模板题 只不过不需要查询 题里只问了全部区间的和,所以seg[ ...
- [HDU] 1698 Just a Hook [线段树区间替换]
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 1698 Just a Hook(线段树区间替换)
题目地址:pid=1698">HDU 1698 区间替换裸题.相同利用lazy延迟标记数组,这里仅仅是当lazy下放的时候把以下的lazy也所有改成lazy就好了. 代码例如以下: # ...
- hdu - 1689 Just a Hook (线段树区间更新)
http://acm.hdu.edu.cn/showproblem.php?pid=1698 n个数初始每个数的价值为1,接下来有m个更新,每次x,y,z 把x,y区间的数的价值更新为z(1<= ...
- HDU.1689 Just a Hook (线段树 区间替换 区间总和)
HDU.1689 Just a Hook (线段树 区间替换 区间总和) 题意分析 一开始叶子节点均为1,操作为将[L,R]区间全部替换成C,求总区间[1,N]和 线段树维护区间和 . 建树的时候初始 ...
- HDU.1556 Color the ball (线段树 区间更新 单点查询)
HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...
- Just a Hook 线段树 区间更新
Just a Hook In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of t ...
随机推荐
- Theano2.1.7-基础知识之设置的配置和编译模式
来自:http://deeplearning.net/software/theano/tutorial/modes.html Configuration Settings and Compiling ...
- UC~移动端的IE!!!坑总结
1.接入过WAP版支付宝支付的应该会发现,支付宝页面在UC中巨丑,完全就是诺基亚时代的网页.你可能会怪它是支付宝的问题吧.但你用QQ浏览器打开,很好啊:你在电脑用火狐.Chrome打开都很好啊:那你试 ...
- Javascript将构造函数扩展为简单工厂
一般而言,在Javascript中创建对象时需要使用关键字new(按构造函数去调用),但是某些时候,开发者希望无论new关键字有没有被显式使用,构造函数都可以被正常调用,即构造函数同时还具备简单工厂的 ...
- innerHeight,clientHeight,offsetHeight,scrollWidth等的区别和用法
要理解这几个属性,首先要搞明白body,documentElement的区别 1.body是DOM对象里的body子节点,即<body>标签2.documentElement是整个节点树的 ...
- 工作框架各种使用整理---使用Cache
<service verb="get" noun="Products"> <implements service="sang.pro ...
- 微信公众平台消息接口开发之微信浏览器HTTP_USER_AGENT判断
在微信公众平台的开发过程中,我们有时需要开发网页并判断是否是是来自微信浏览器访问,本文介绍如何做出这一判断. 一.$_SERVER数组 $_SERVER 是一个包含了诸如头信息(header).路径( ...
- 消息队列写入内容后,读出来的自动包裹了<string>标签,自定义格式化器解决该issue
/// <summary> /// 该格式化器使输入即输出 /// </summary> public class StringFormatter : IMessageForm ...
- Beta版冲刺Day1
会议讨论: 628: 已经成功实现了文件的上传功能,但是按钮的布局有点不好看.未完成的功能有:修改老师信息时候弹出小窗口进行修改. 601: 目前还在解决剩下的问题,比如将 ...
- 顺序栈C语言实现
"` #include <stdio.h> #define MAXSIZE 10001 #define ELEMTYPE int #define STACK_EMPTY -999 ...
- Windows配置mycat
MyCat使用Mysql的通讯协议模拟成一个MySQl服务器,并建立了完整的Schema(数据库).Table(数据表).User(用户)的逻辑模型,并将这套逻辑模型映射到后端的存储节点DataNod ...

