zoukankan      html  css  js  c++  java
  • 线段树专辑——hdu 1698 Just a Hook

    http://acm.hdu.edu.cn/showproblem.php?pid=1698

    这是一个区间染色的问题,对于区间染色问题,通常的方法是在线段树中定义一个cover域,当cover的值为-1的时候,则表示这个线段的覆盖不是有一个颜色染成的,其中包含了多种颜色,而当cover为一个非-1的值时,例如cover==1时表示该线段是有第一种颜色染成的。 对于这题,由于是成段成段的在跟新线段树,我们自然不能简单的递归到根节点再进行处理,这样毫无疑问是要超时的,所以我们只能成段的跟新。

    那么,如何做到成段的跟新呢?这里需要运用一种叫着lazy的思想,lazy顾名思义便是懒惰的意思。该思想大概的意思便是:假设要跟新区间[a,b],那么当我们找到区间[a,b]时,便不再往下进行递归,而是在该区间上标记上一个lazy,表示这里有信息需要向下传递。那么当我们需要跟新区间[a,b/2]时,我们便一定会从区间[a,b]经过,经过的过程中,我们发现区间[a,b]有信息需要向下传递,此时便将区间[a,b]的信息传递给其子区间。这样在必要的时候才一层一层的传递,便节约了很多时间。具体见程序吧,很清晰的

    View Code
     1 #include<iostream>
    2 #include<string>
    3 using namespace std;
    4
    5 struct node
    6 {
    7 int l;
    8 int r;
    9 int cover;
    10 };
    11
    12 node tree[500000];
    13 int n,m;
    14
    15 void build(int i,int l,int r)
    16 {
    17 tree[i].l=l;
    18 tree[i].r=r;
    19 tree[i].cover=1; //初始颜色为1
    20 if(l==r)
    21 return;
    22 int mid=(l+r)/2;
    23 build(2*i,l,mid);
    24 build(2*i+1,mid+1,r);
    25 }
    26
    27 void updata(int i,int l,int r,int w)
    28 {
    29 if(tree[i].l>r || tree[i].r<l)
    30 return;
    31 if(tree[i].l>=l && tree[i].r<=r)
    32 {
    33 tree[i].cover=w; //cover表示lazy标记,当cover的值不为-1的时候,就说明该区间有信息需要向下传递
    34 return;
    35 }
    36 if(tree[i].cover!=-1) //该区间有信息需要传递
    37 {
    38 tree[2*i].cover=tree[2*i+1].cover=tree[i].cover; //将其标记传递给子区间
    39 tree[i].cover=-1; //同时自身取消标记
    40 }
    41 updata(2*i,l,r,w);
    42 updata(2*i+1,l,r,w);
    43 }
    44
    45 int ans;
    46 void find(int i)
    47 {
    48 if(tree[i].cover!=-1) //单色区间,直接取其值
    49 {
    50 ans+=(tree[i].r-tree[i].l+1)*tree[i].cover;
    51 return;
    52 }
    53 if(tree[i].l==tree[i].r)
    54 return;
    55 find(2*i); //非单色区间,则向下递归
    56 find(2*i+1);
    57 }
    58
    59 int main()
    60 {
    61 int cas,i,a,b,c,o=1;
    62 freopen("in.txt","r",stdin);
    63 scanf("%d",&cas);
    64 while(cas--)
    65 {
    66 scanf("%d%d",&n,&m);
    67 build(1,1,n);
    68 for(i=0;i<m;i++)
    69 {
    70 scanf("%d%d%d",&a,&b,&c);
    71 updata(1,a,b,c);
    72 }
    73 ans=0;
    74 find(1);
    75 printf("Case %d: The total value of the hook is %d.\n",o++,ans);
    76 }
    77 return 0;
    78 }
  • 相关阅读:
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 最大的元素距离
    Java 第十一届 蓝桥杯 省模拟赛 递增序列
    Java 第十一届 蓝桥杯 省模拟赛 递增序列
    Java 第十一届 蓝桥杯 省模拟赛 最大的元素距离
  • 原文地址:https://www.cnblogs.com/ka200812/p/2242248.html
Copyright © 2011-2022 走看看