Just a Hook

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 32434    Accepted Submission(s): 15927

Problem 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 Input
1
10
2
1 5 2
5 9 3
 
Sample Output
Case 1: The total value of the hook is 24.
 
Sourcghf
与前面几道显然的不同,前面几道都是对于某一个点的修改这个则是对一整段区间所有的元素都修改。
先回忆下为什么对一个点进行修时复杂度为logN,也就是树高,对于树上的结点对应的区间,其两个子节点中一定有一个包含这个待修改节点且另一个子节点不包含,
所以我们每次在每一层修改一个节点的值即可,树高~=logN所以修改了logN次。
查询时同理最多2*logN次(因为查找区间可能在两个子节点中都有重合部分)
 
对于区间修改如果还是这么来的话修改量可能会很大,比如对于[1,10]修改[1,10],则需要修改整棵树,计算量自然庞大。
于是引进了lazy标记的做法,股,顾名思义他不会及时的修改所有的点而是先记录下来,到需要查询时在释放。
 
pushdown()函数,即调整lazy标记函数,如果当前点存在lazy标记,我们对他进行调整,首先将标记传递给两个儿子并取消自身的标记,接着对于这个标记调整左右儿子的值。
在update()中使用的意义: 对于待修改节点,如果此节点区间完全包含于修改区间,显然以此节点为根的子树都需要修改,我们不这么做而是只修改这个节点的值并对其做上lazy标记  
在查询时如果到了这个结点那么就释放标记给子节点,如果根本没访问过这个节点显然也不需要多此一举的释放标记。
含义就是对于一些反复进行的大区间的修改,我们只是修改了几次标记而已查询时顺路释放这样减少了很多更新时的操作从而降低了复杂度!
 
#include<bits/stdc++.h>
using namespace std;
#define lc (o<<1)
#define rc (o<<1|1)
#define mid ((L+R)>>1)
const int maxn=100000;
int Q[maxn<<2];
int laz[maxn<<2];
void build(int o,int L,int R)
{
  if(L==R) {Q[o]=1;return;}
  else{
    build(lc,L,mid);
    build(rc,mid+1,R);
    Q[o]=Q[lc]+Q[rc];
  }
}
void pushdown(int o,int L,int R)
{
  if(laz[o]!=-1){
    laz[lc]=laz[rc]=laz[o];
    Q[lc]=laz[o]*(mid-L+1);
    Q[rc]=laz[o]*(R-mid);
    laz[o]=-1;
  }
}
void update(int o,int L,int R,int l,int r,int v)
{
 if(L>=l&&R<=r){
    Q[o]=v*(R-L+1);
    laz[o]=v;
    return;
 }
 else{
  pushdown(o,L,R);
  if(l<=mid) {update(lc,L,mid,l,r,v);}
  if(r>mid)  {update(rc,mid+1,R,l,r,v);}
 }
 Q[o]=Q[lc]+Q[rc];
}
int query(int o,int L,int R,int l,int r)
{
  if(L>=l&&R<=r) return Q[o];
  pushdown(o,L,R);
  if(r<=mid) return query(lc,L,mid,l,r);
  else if(l>mid) return query(rc,mid+1,R,l,r);
  else return query(lc,L,mid,l,r)+query(rc,mid+1,R,l,r);
}
int main()
{
    int n,m,i,j,k=0,t;
    scanf("%d",&t);
    while(t--){
    scanf("%d",&n);
    int q;
    memset(laz,-1,sizeof(laz));
        build(1,1,n);
        scanf("%d",&q);
        while(q--){
            int a,b,c,z;
                scanf("%d%d%d",&a,&b,&c);
                update(1,1,n,a,b,c);
        }
       printf("Case %d: The total value of the hook is %d.\n",++k,Q[1]);
    }
    return 0;
}

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

HDU1698 线段树入门之区间修改/查询(lazy标记法)的更多相关文章

  1. codevs1081 线段树练习 2<区间修改>

    1081 线段树练习 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master   题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有 ...

  2. poj3468区间加减查找——树状数组区间修改查询

    题目:http://poj.org/problem?id=3468 增加一个更改量数组,施以差值用法则区间修改变为单位置修改: 利用公式可通过树状数组维护两个数组:f与g而直接求出区间和. 代码如下: ...

  3. kb-07线段树-05-区间整体修改查询;(水)

    /* */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; s ...

  4. hiho1080 - 数据结构 线段树(入门题,两个lazy tag)

    题目链接 维护区间和,两个操作:一个是将某个区间设置成一个值,一个是将某个区间增加一个固定值 /**************************************************** ...

  5. 【codevs】1082 线段树练习 3 <区间修改+区间和>

    题目连接   http://codevs.cn/problem/1082/ Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. In ...

  6. 约会安排 HDU - 4553(线段树区间查询,区间修改,区间合并)

    题目: 寒假来了,又到了小明和女神们约会的季节.  小明虽为屌丝级码农,但非常活跃,女神们常常在小明网上的大段发言后热情回复“呵呵”,所以,小明的最爱就是和女神们约会.与此同时,也有很多基友找他开黑, ...

  7. HDU1698(线段树入门题)

    Just a Hook Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Descrip ...

  8. hdu1754(线段树单点替换&区间最值模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 题意:中文题诶- 思路:线段树单点替换&区间最大值查询模板 代码: #include & ...

  9. POJ 2155 Matrix (二维线段树入门,成段更新,单点查询 / 二维树状数组,区间更新,单点查询)

    题意: 有一个n*n的矩阵,初始化全部为0.有2中操作: 1.给一个子矩阵,将这个子矩阵里面所有的0变成1,1变成0:2.询问某点的值 方法一:二维线段树 参考链接: http://blog.csdn ...

随机推荐

  1. 利用Dockerfile构建一个基于CentOS 7镜像

    利用Dockerfile构建一个基于CentOS 7,包括java 8, tomcat 7,php ,mysql+mycat的镜像. Dockerfile内容如下: FROM centosMAINTA ...

  2. 设计模式之——Decorator模式

    Decorator模式又叫装饰者模式,这种模式是为了满足Java开发的"面向扩展开放,面向修改闭源"的开发原则设计出来的. 在装饰者模式中,不修改源类的代码,却能修改源类中方法的功 ...

  3. Django - ORM - 进阶

    一.多表操作 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是 ...

  4. 洛谷P1858 多人背包 多人背包板子题/多人背包学习笔记

    ,,,本来自以为,我dp学得还挺好的 然后今天一考发现都不会啊QAQ 连最基础的知识点都不清楚啊QAQ 所以就来写个题解嘛! 先放下板子题 其实我jio得,这题只要大概了解方法就不是很难鸭,,,毕竟是 ...

  5. CSS背景以及文本

    css设置背景: <style type="text/css"> /*background-image: 直接设置x,y重复而且平铺整个body*/ /*下面两句的功能 ...

  6. git-【四】撤销修改和删除文件操作

    一:撤销修改: 比如我现在在readme.txt文件里面增加一行 内容为555555555555,我们先通过命令查看如下: 在未提交之前,发现添加5555555555555内容有误,所以得马上恢复以前 ...

  7. Openstack(十二)部署neuron(计算节点)

    在计算节点安装 12.1安装neuron(计算节点) # yum install openstack-neutron-linuxbridge ebtables ipset –y 12.2配置neutr ...

  8. VC中加载LIB库文件的三种方法

    VC中加载LIB库文件的三种方法 在VC中加载LIB文件的三种方法如下: 方法1:LIB文件直接加入到工程文件列表中   在VC中打开File View一页,选中工程名,单击鼠标右键,然后选中&quo ...

  9. cocos代码研究(11)ActionManager类学习笔记

    理论部分 ActionManager是一个单例类,管理所有动作. 通常你不需要直接使用这个类.大多情况下,你将使用Node的接口,它提供了更友好的封装 但也有一些情况下,你可能需要使用这个单例. 示例 ...

  10. YTD易出现断层问题,请注意!

    declare @table table( company_id int ,--公司编号 quarter_num ),--季度 disti ),--分销商 num int --数量 ) insert ...