• 线段树专辑——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 }
  • 相关阅读:
    ios 读取通讯录
    隐藏多余的分割线
    Cell高亮时设置cell内容
    iOS录音
    iOS发送信息功能(生成信息内容)
    iOS颜色选择器
    iOS缓存
    二维码扫描
    梵讯笔记
    微信开发后台库
  • 原文地址:https://www.cnblogs.com/ka200812/p/2242248.html
Copyright © 2020-2023  润新知