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;
}
zoj 3573 Under Attack(线段树 标记法 最大覆盖数)的更多相关文章
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- hdu 4578 线段树(标记处理)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others) ...
- hdu 3954 线段树 (标记)
Level up Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- BZOJ4785 [Zjoi2017]树状数组 【二维线段树 + 标记永久化】
题目链接 BZOJ4785 题解 肝了一个下午QAQ没写过二维线段树还是很难受 首先题目中的树状数组实际维护的是后缀和,这一点凭分析或经验或手模观察可以得出 在\(\mod 2\)意义下,我们实际求出 ...
- Codeforces 258E - Little Elephant and Tree(根号暴力/线段树+标记永久化/主席树+标记永久化/普通线段树/可撤销线段树,hot tea)
Codeforces 题目传送门 & 洛谷题目传送门 yyq:"hot tea 不常有,做过了就不能再错过了" 似乎这是半年前某场 hb 模拟赛的 T2?当时 ycx.ym ...
- zoj 3511 Cake Robbery(线段树)
problemCode=3511" target="_blank" style="">题目链接:zoj 3511 Cake Robbery 题目 ...
- hdu 4031 Attack 线段树
题目链接 Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total ...
- P3332 [ZJOI2013]K大数查询(线段树套线段树+标记永久化)
P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树 把插入的值离散化一下开个线段树 蓝后每个节点开个线段树,维护一下每个数出现的区间和次数 为了防止MLE动态开点就好辣 重点是标记永久 ...
- 洛谷P3437 [POI2006]TET-Tetris 3D(二维线段树 标记永久化)
题意 题目链接 Sol 二维线段树空间复杂度是多少啊qwqqq 为啥这题全网空间都是\(n^2\)还有人硬要说是\(nlog^2n\)呀.. 对于这题来说,因为有修改操作,我们需要在外层线段树上也打标 ...
随机推荐
- day14 迭代器,生成器,函数的递归调用
1.什么是迭代器 迭代是一个重复的过程,但是每次重复都是基于上一次重复的结果而继续 迭代取值的工具 2.为什么要用迭代器 迭代器的优点 ①不依赖于索引取值 ②更节省内存 缺点: 1.不如按 ...
- PAT Basic 1072
1072 开学寄语 下图是上海某校的新学期开学寄语:天将降大任于斯人也,必先删其微博,卸其 QQ,封其电脑,夺其手机,收其 ipad,断其 wifi,使其百无聊赖,然后,净面.理发.整衣,然后思过.读 ...
- Leetcode 385.字典序排序
字典序排序 给定一个整数 n, 返回从 1 到 n 的字典顺序. 例如, 给定 n =1 3,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] . 请尽可能的优化算法的时间复杂度和 ...
- Terracotta2
Terracotta 3.2.1简介 (二) Terracotta分布式缓存EhcacheQuartzTerracotta的web session方案 高效.高可用的Web Session解决方案 ...
- BZOJ-1507 文本编辑器(Editor)
一道极其相似的题...http://hi.baidu.com/8361101/item/5b149103cbf4007cbee97e5f 就多了个区间查找,少了个翻转... 少了翻转的话貌似可以不用S ...
- BZOJ 3238 [Ahoi2013]差异 ——后缀自动机
后缀自动机的parent树就是反串的后缀树. 所以只需要反向构建出后缀树,就可以乱搞了. #include <cstdio> #include <cstring> #inclu ...
- 王室联邦(bzoj 1086)
Description “余”人国的国王想重新编制他的国家.他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成员来管理.他的国家有n个城市,编号为1..n.一些城市之间有道路相连,任意两个不 ...
- 洛谷 [P4035] 球形空间生成器
高斯消元 注意浮点误差,判断一个浮点数是否为 0 的时候,看他的绝对值与 \(10^{-8}\)的关系 #include <iostream> #include <algorithm ...
- Codevs 1299 切水果 水一发
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 简单的说,一共N个水果排成一排,切M次,每次切[L,R]区间的所有水果(可能有的 ...
- 【HDOJ6223】Infinite Fraction Path(后缀数组,倍增)
题意: 给一个长度为n的字符串s[0..n-1],但i的后继不再是i+1,而是(i*i+1)%n,求所有长度为n的“子串”中,字典序最大的是谁 n<=150000,s[i]=0..9 思路:后缀 ...