舒哥的blog

www.6aiq.com AIQ-机器学习大数据技术社区 全国最专业的机器学习大数据技术社区。全国IT精英群号:467123855...

zoj 3573 Under Attack(线段树 标记法 最大覆盖数)
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;
}




阅读更多
版权声明:www.6aiq.com AIQ-机器学习大数据技术社区 全国最专业的机器学习大数据技术社区,机器学习与人工智能AI的前沿阵地,提供各种国内外第一手的机器学习、人工智能资源资讯学习资料,是一个以机器学习,大数据,云计算,数据分析,数据挖掘,人工智能,区块链为主要学习方向的学习交流社区。大家可以分享高质量文章 。全国高校IT精英群号:467123855 https://blog.csdn.net/lsgqjh/article/details/46801867
个人分类: 树状数组-线段树
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

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

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭