题目链接: 传送门

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(线段树/区间更新)的更多相关文章

  1. (简单) HDU 1698 Just a Hook , 线段树+区间更新。

    Description: In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of ...

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

  3. HDU 1698 Just a Hook 线段树区间更新、

    来谈谈自己对延迟标记(lazy标记)的理解吧. lazy标记的主要作用是尽可能的降低时间复杂度. 这样说吧. 如果你不用lazy标记,那么你对于一个区间更新的话是要对其所有的子区间都更新一次,但如果用 ...

  4. HDU 1698 Just a Hook(线段树 区间替换)

    Just a Hook [题目链接]Just a Hook [题目类型]线段树 区间替换 &题解: 线段树 区间替换 和区间求和 模板题 只不过不需要查询 题里只问了全部区间的和,所以seg[ ...

  5. [HDU] 1698 Just a Hook [线段树区间替换]

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. HDU 1698 Just a Hook(线段树区间替换)

    题目地址:pid=1698">HDU 1698 区间替换裸题.相同利用lazy延迟标记数组,这里仅仅是当lazy下放的时候把以下的lazy也所有改成lazy就好了. 代码例如以下: # ...

  7. hdu - 1689 Just a Hook (线段树区间更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=1698 n个数初始每个数的价值为1,接下来有m个更新,每次x,y,z 把x,y区间的数的价值更新为z(1<= ...

  8. HDU.1689 Just a Hook (线段树 区间替换 区间总和)

    HDU.1689 Just a Hook (线段树 区间替换 区间总和) 题意分析 一开始叶子节点均为1,操作为将[L,R]区间全部替换成C,求总区间[1,N]和 线段树维护区间和 . 建树的时候初始 ...

  9. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

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

随机推荐

  1. FineUI参考手册(离线版)现已免费提供下载!

    http://fineui.com/bbs/forum.php?mod=viewthread&tid=3473

  2. Qt学习笔记 QMessageBox

    Qt的几种MessageBox 1.Infomation类型 QMessageBox::information(this,tr("hello"),tr("title&qu ...

  3. Vue学习笔记-2

    前言 本文非vue教程,仅为学习vue过程中的个人理解与笔记,有说的不正确的地方欢迎指正讨论 1.computed计算属性函数中不能使用vm变量 在计算属性的函数中,不能使用Vue构造函数返回的vm变 ...

  4. ionic —— 开发环境搭建并编译运行第一个APP

    其实类似的环境已经玩了很多次了,最开始玩还是微信刚刚出来,那会儿没有智能机.只好安装一个模拟器,却只是为了注册一个微信.想想也就是够了~ 前前后后折腾了很多次,可是每一次都给人不一样的感觉,也许是这个 ...

  5. Excel——将内容导入

    1.写入Excel文件的操作引入Microsoft.Office.Tools.Excel.dll 程序集 List<Person> list = new List<Person> ...

  6. mybatis resultMap映射学习笔记

    这几天,百度mybatis突然看不到官网了,不知道百度怎么整的.特此贴出mybatis中文官网: http://www.mybatis.org/mybatis-3/zh/index.html 一个学习 ...

  7. Hibernate 的dialect 大全

    RDBMS 方言 DB2 org.hibernate.dialect.DB2Dialect DB2 AS/400 org.hibernate.dialect.DB2400Dialect DB2 OS3 ...

  8. redis HA高可用方案Sentinel和shard

    1.搭建redis-master.redis-slave以及seninel哨兵监控 在最小配置:master.slave各一个节点的情况下,不管是master还是slave down掉一个,“完整的” ...

  9. Collections的应用

    Collection : 接口  Collections : 集合的工具类    Arrays (数组的工具类)  只能操作list集合    说出Collection和Collections 的区别 ...

  10. Beta版本冲刺———第二天

    会议照片: 项目燃尽图: 1.项目进展: 昨天的困难:分数排行榜的设计 今天解决的进度:完成了界面优化以及建立新的排行榜选项卡界面. 明天要做的事情:分数排行榜的功能设计 2.每个人每天做的事情 郭怡 ...