zoj 3573 Under Attack(线段树 标记法 最大覆盖数)

原创 2015年07月08日 12:30:04
Under Attack




Time Limit:  10 Seconds      Memory Limit:  65536 KB 




Doctor serves at a military air force base. One day, the enemy launch a sudden attack and the base is under heavy fire. The fighters in the airport must take off to intercept enemy bombers. However, the enemies know this clearly and they now focus on destroying the runway. The situation is becoming worse rapidly! 


Every part of the runway has a damage level. On each bombing run, the damage level is increased by the bomb's damage . Fortunately, the enemy bombers has to stop bombing the runway when they run out of ammo. Then the ground crew have time to evaluate the situation of runway so that they can come to repair the runway ASAP after enemy attacks. The most heavily-damaged part on fighters' taking off and landing path should first be repaired. Assume that runway start from north and head to south , and fighters will take off or land only from north to south or vice versa. 


Now that the task is clear, the ground crew need the cooridinates of two points: first that is the most damaged point from north to south, second is the most damaged point from south to north.The base's central mainframe is down under hacker attack. So Doctor could only use his poor little and shabby notebook to fulfill this task. Can you help him? 


Input


The input consists of multiple cases. 
The first line is the runway length L. L can be up to 15000.
 Next lines will describe enemy bombing runs ,each line describes effect range start end of each bombing run and enemy bomb damage d.if start is -1, this case ends..
There can be up to 3000 bombing run, each time the damage is up to 100. 
 Notice that the bombing range is from north to south, and runway range is [0,len].




Output


Output the cooridinates of two points: first that is the most damaged point from north to south, second is the most damaged point from south to north. 


Sample Input
10
1 5 2
6 9 2
-1 -1 -1




Sample Output
1 9




从早上起 这都一上午了,这个大水题终于a了!在不知道 最大覆盖次数求法之前,我先求出全长线段中最大值,也就是普通的区间更新加延迟标记,然后利用calculate函数从两边分别开始遍历找到左右最大值的位置,从多组测试数据上来看 ,并没有什么差错,但就是wrong,后学会最大覆盖次数,1a。
见到的请帮我看看到底是哪些 数据错了!!!!!!


第二段代码是正确地;


wrong code:
#include<iostream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<cctype>
#include<string>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;
const int INF=15003;
struct Tree
{
    int left;
    int right;
    int mark;
    int Max;
} tree[INF<<2];

int create(int root,int left,int right)
{
    tree[root].left=left;
    tree[root].right=right;
    if(left==right)
    {
        return tree[root].Max=0;
    }
    int a,b,middle=(left+right)>>1;
    a=create(root<<1,left,middle);
    b=create(root<<1|1,middle+1,right);
    return tree[root].Max=max(a,b);
}

void update_mark(int root)
{
    if(tree[root].mark)
    {
        tree[root].Max+=tree[root].mark;
        if(tree[root].left!=tree[root].right)
        {
            tree[root<<1].mark+=tree[root].mark;
            tree[root<<1|1].mark+=tree[root].mark;
        }
        tree[root].mark=0;
    }
}

int calculate(int root,int left ,int right)
{
    update_mark(root);
    if(tree[root].left>right||tree[root].right<left)
        return 0;
    if(tree[root].left>=left&&tree[root].right<=right)
    {
        return tree[root].Max;
    }
    int a,b;
    a=calculate(root<<1,left,right);
    b=calculate(root<<1|1,left,right);
    return max(a,b);
}

int   update(int root,int left,int right,int val)
{
    update_mark(root);
    if(tree[root].left>right||tree[root].right<left)
        return tree[root].Max;
    if(tree[root].left>=left&&tree[root].right<=right)
    {
        tree[root].mark+=val;
        update_mark(root);
        return tree[root].Max;
    }
    int a=update(root<<1,left,right,val);
    int b=update(root<<1|1,left,right,val);
    return tree[root].Max=max(a,b);

}

int main()
{
    int L;
    while(scanf("%d",&L)!=EOF)
    {
        create(1,0,L);
        int x,y,z;
        while(scanf("%d%d%d",&x,&y,&z)!=EOF)
        {
            if(x>y)
                swap(x,y);
            if(x!=-1)
            {
                update(1,x,y,z);
            }
            else break;
        }
        int k=calculate(1,0,L);
        int locl,locr;
        for(int i=0; i<=L;i++)
        {
            if(calculate(1,i,i)==k)
            {

                locl=i;
                break;
            }
        }
        for(int i=L;i>=0;i--)
        {
            if(calculate(1,i,i)==k)
            {
                locr=i;
                break;
            }
        }
        printf("%d,%d\n",locl,locr);
    }
    return 0;
}
/*
10
1 2  3
0 0 3
5 8 4
0 0 3
2 2 2
-1 1 3
*/
</pre><pre name="code" class="cpp">正确 代码:
<pre name="code" class="cpp">#include<stdio.h>
struct Tree
{
    int left,right,cover;
} tree[15000<<2];
int covered=0;
void create(int root,int left,int right)
{
    tree[root].left=left;
    tree[root].right=right;
    tree[root].cover=0;
    if(right==left)
        return ;
    int mid=(left+right)>>1;
    create(root<<1,left,mid);
    create(root<<1|1,mid+1,right);
}

void update(int root,int left,int right,int val)
{
    if(left<=tree[root].left&&tree[root].right<=right)
    {
        tree[root].cover+=val;
        return ;
    }
    int m=(tree[root].left+tree[root].right)>>1;
    if(m>=left)update(root<<1,left,right,val);
    if(m<right)update(root<<1|1,left,right,val);
}

void  calculate(int root,int x)
{
    covered+=tree[root].cover;
    if(tree[root].left==tree[root].right)
        return ;
    int m=(tree[root].left+tree[root].right)>>1;
    if(m>=x)
        calculate(root<<1,x);
    else
        calculate(root<<1|1,x);

}

int main()
{
    int L;
    while(scanf("%d",&L)!=EOF)
    {
        create(1,0,L);
        int x,y,z;
        while(scanf("%d%d%d",&x,&y,&z))
        {
            if(x==-1)
                break;
            update(1,x,y,z);
        }
        int loc1, loc2,Max=0;
        for(int i=0; i<=L; i++)
        {
            covered=0;
            calculate(1,i);
            if(covered>Max)
            {
                Max=covered;
                loc1=i;
            }
        }
        for(int i=L,Max=0; i>=0; i--)
        {
            covered=0;
            calculate(1,i);
            if(covered>Max)
            {
                Max=covered;
                loc2=i;
            }
        }
        printf("%d %d\n",loc1,loc2);
    }
    return 0;
}




版权声明:强烈建议大家加入(Java)全国各校IT精英! 群号 467123855 里面都是大神各种分享 内推渠道 (我的老豆比IT站被阿里销毁了。。。)

ZOJ 3573 Under Attack (线段树两边维护最大值)

Doctor serves at a military air force base. One day, the enemy launch a sudden attack and the base i...
  • qq_37497322
  • qq_37497322
  • 2017年08月03日 20:31
  • 144

Camel标记法、Pastal标记法和匈牙利标记法

为了代码清晰易懂,通常变量名采用一些著名的命名规则,主要有Camel标记法,Pastal标记法和匈牙利标记法。       Camel标记法采用首字母小写,接下来的单词都以大写字母开头的方法,如...
  • a986465807
  • a986465807
  • 2014年11月17日 17:37
  • 154

时间复杂度与大O记法的理解

算法,时间复杂度
  • u014745194
  • u014745194
  • 2017年05月24日 17:00
  • 742

ZOJ 3209 Treasure Map(精确覆盖问题&舞蹈链)

题目链接:[kuangbin带你飞]专题三 Dancing Links B - Treasure Map题意 给一矩形和k个小矩形,问选取最小数量为多少的小矩形可以对大矩形进行精确覆盖。 思路 ...
  • to_be_better
  • to_be_better
  • 2016年02月21日 18:50
  • 900

二分图 最小覆盖数 = 最大匹配数、最大独立集 = 总数-最小覆盖集 证明 hdu 1068

二分图有两个定理:最小覆盖数=最大匹配数、最大独立集=总数-最小覆盖集 。 这里来给出证明(如果还不懂匈牙利算法,请先看之前写的一篇)匈牙利算法链接 几个基本定义: 最小覆盖:即在所有顶点中选择最少的...
  • Techmonster
  • Techmonster
  • 2015年11月24日 13:19
  • 2073

压入与重标记算法(预流推进算法)

最大流算法之压入与重标记算法(预流推进算法) 今天是平安夜,明天是圣诞节,明天也是我的生日, 到目前都是直接贴代码,懒动手,今天好好写一篇博客。                            ...
  • u011659057
  • u011659057
  • 2013年12月24日 18:07
  • 2774

二分图最大匹配,最小路径覆盖,最小点覆盖,最大独立集,最小边覆盖与建图方法

前言:         有自己写的,有摘的别人的,前面是摘的,也是无心整理,出错是难免的,反正我都不会证明,智人见智,别被我误导了。 §1图论点、边集和二分图的相关概念和性质 点覆盖、最小点覆盖...
  • hitwhacmer1
  • hitwhacmer1
  • 2015年07月02日 01:10
  • 2754

数组元素标记法

点击打开链接 管闲事的小明 时间限制:4000 ms  |  内存限制:65535 KB 难度:2 描述某校大门外长度为L的马路上有一排树,...
  • ruruozhenhao
  • ruruozhenhao
  • 2017年07月27日 15:31
  • 210

匈牙利标记法

匈牙利标记法 匈牙利符号表示法     如果你正在动作一个像Microsoft一样的公司,有几千个程序员都在干不同的项目 ,在某一点上就应当提出一个编写代码的标准方式。否则,结果将是一片混乱。因...
  • HW140701
  • HW140701
  • 2016年04月13日 09:15
  • 374

lua 垃圾回收标记函数 reallymarkobject

lua垃圾回收标记函数
  • vinsberg
  • vinsberg
  • 2015年11月21日 23:08
  • 258
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:zoj 3573 Under Attack(线段树 标记法 最大覆盖数)
举报原因:
原因补充:

(最多只允许输入30个字)