Man Down

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1836    Accepted Submission(s): 665

Problem Description
The Game “Man Down 100 floors” is an famous and interesting game.You can enjoy the game from 
http://hi.baidu.com/abcdxyzk/blog/item/16398781b4f2a5d1bd3e1eed.html

We take a simplified version of this game. We have only two kinds of planks. One kind of the planks contains food and the other one contains nails. And if the man falls on the plank which contains food his energy will increase but if he falls on the plank which contains nails his energy will decrease. The man can only fall down vertically .We assume that the energy he can increase is unlimited and no borders exist on the left and the right.

First the man has total energy 100 and stands on the topmost plank of all. Then he can choose to go left or right to fall down. If he falls down from the position (Xi,Yi),he will fall onto the nearest plank which satisfies (xl <= xi <= xr)(xl is the leftmost position of the plank and xr is the rightmost).If no planks satisfies that, the man will fall onto the floor and he finishes his mission. But if the man’s energy is below or equal to 0 , he will die and the game is Over.

Now give you the height and position of all planks. And ask you whether the man can falls onto the floor successfully. If he can, try to calculate the maximum energy he can own when he is on the floor.(Assuming that the floor is infinite and its height is 0,and all the planks are located at different height).

 
Input
There are multiple test cases.

For each test case, The first line contains one integer N (2 <= N <= 100,000) representing the number of planks.

Then following N lines representing N planks, each line contain 4 integers (h,xl,xr,value)(h > 0, 0 < xl < xr < 100,000, -1000 <= value <= 1000), h represents the plank’s height, xl is the leftmost position of the plank and xr is the rightmost position. Value represents the energy the man will increase by( if value > 0) or decrease by( if value < 0) when he falls onto this plank.

 
Output
If the man can falls onto the floor successfully just output the maximum energy he can own when he is on the floor. But if the man can not fall down onto the floor anyway ,just output “-1”(not including the quote)
 
Sample Input
4
10 5 10 10
5 3 6 -100
4 7 11 20
2 2 1000 10
 
Sample Output
140
 
Source
 
 
题目意思:
一个人初始能量为100,从最高的木板下落,每次下路一定在木板的边界。每个木板有一个价值,当人到达这个木板的时候可以获得这个价值(价值有正有负),若在中途能量变为0或负数则输出-1,否则输出到达地面后剩余最大的能量。
 
思路:
先按木板高度从小到大排序,依次插入线段树中,并获得覆盖之前线段树中木板标号,建图,spfa跑一遍。
 
代码:
 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
using namespace std; #define N 100005
#define ll root<<1
#define rr root<<1|1
#define mid (a[root].l+a[root].r)/2 int n;
vector<int>ve[N]; struct Line{
int h, l, r, val;
}b[N]; bool cmp(Line a,Line b){
return a.h<b.h;
} struct node{
int l, r, val;
bool lazy;
}a[N*]; void build(int l,int r,int root){
a[root].l=l;
a[root].r=r;
a[root].lazy=false;
a[root].val=;
if(l==r) return;
build(l,mid,ll);
build(mid+,r,rr);
} void update(int l,int r,int val,int root){
if(a[root].l==l&&a[root].r==r){
a[root].lazy=true;
a[root].val=val;
return;
}
if(r<=a[ll].r) update(l,r,val,ll);
else if(l>=a[rr].l) update(l,r,val,rr);
else{
update(l,mid,val,ll);
update(mid+,r,val,rr);
}
} int query(int p,int root){
if(a[root].l==a[root].r&&a[root].l==p){
return a[root].val;
}
if(a[root].lazy){
a[ll].lazy=a[rr].lazy=true;
a[root].lazy=false;
a[ll].val=a[rr].val=a[root].val;
}
if(p<=a[ll].r) return query(p,ll);
else return query(p,rr);
} bool visited[N];
int dis[N]; void spfa(int root){
queue<int>Q;
Q.push(root);
memset(visited,false,sizeof(visited));
visited[root]=true;
for(int i=;i<=n;i++) dis[i]=-;
dis[root]=+b[root].val;
int i, u, v;
while(!Q.empty()){
u=Q.front();Q.pop();visited[u]=false;
for(i=;i<ve[u].size();i++){
v=ve[u][i];
if(v&&dis[v]<dis[u]+b[v].val&&dis[u]+b[v].val>){
dis[v]=dis[u]+b[v].val;
if(!visited[v]){
Q.push(v);visited[v]=true;
}
}
else if(!v&&dis[v]<dis[u]){
dis[v]=dis[u];
}
}
}
} main()
{
int i, j, k;
int maxh, minh;
while(scanf("%d",&n)==){
maxh=-;
minh=;
for(i=;i<=n;i++) {
scanf("%d %d %d %d",&b[i].h,&b[i].l,&b[i].r,&b[i].val);
maxh=max(maxh,b[i].r);
minh=min(minh,b[i].l);
}
build(minh,maxh,);
sort(b+,b+n+,cmp);
for(i=;i<=n;i++) ve[i].clear();
int l, r;
for(i=;i<=n;i++){
l=query(b[i].l,);
r=query(b[i].r,);
if(l==r) ve[i].push_back(l);
else{
ve[i].push_back(l);
ve[i].push_back(r);
}
update(b[i].l,b[i].r,i,);
}
spfa(n);//n为最高木板标号,0为地面
if(dis[]>) printf("%d\n",dis[]);
else printf("-1\n");
}
}

HDU 3016 线段树区间更新+spfa的更多相关文章

  1. HDU 1698 线段树 区间更新求和

    一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...

  2. hdu 1698 线段树 区间更新 区间求和

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. HDU(1698),线段树区间更新

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 区间更新重点在于懒惰标记. 当你更新的区间就是整个区间的时候,直接sum[rt] = c*(r- ...

  4. HDU 1698 (线段树 区间更新) Just a Hook

    有m个操作,每个操作 X Y Z是将区间[X, Y]中的所有的数全部变为Z,最后询问整个区间所有数之和是多少. 区间更新有一个懒惰标记,set[o] = v,表示这个区间所有的数都是v,只有这个区间被 ...

  5. HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...

  6. HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...

  7. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  8. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

  9. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

随机推荐

  1. Web 通信 之 长连接、长轮询(转)

    Web 通信 之 长连接.长轮询(long polling) 基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强 ...

  2. C++ 学习笔记(3) —— 內联函数

    内联函数的用处: 用空间换取时间,在调用时不用每次都写调用的汇编. 什么时候内联: 比较小的函数:只有两三行 在循环里循环调用的函数 什么时候不内联: 比较大的函数,2.30行的 递归的函数

  3. C# property简介

    property专属的关键字就只有value.其他的性质实现都是用其他的方法的组合.property通过对一系列方法的灵活组合应用,能够间接地对私有的成员变量进行赋值操作和得到值.因为是间接地,私有变 ...

  4. getopt解析命令行参数一例:汇集多个服务器的日志

    高效工作的一个诀窍就是尽可能自动化, 简便化. 比如, 公司里, 要搜索多个集群下的应用日志来排查问题, 需要使用 pssh: pssh -i -h api_hangzhou.iplist " ...

  5. python学习笔记七 初识socket(进阶篇)

    socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...

  6. winform基础,主要控件简单介绍,以及小练习

    WinForm - C/S B/S 客户端应用程序 - 是需要安装在用户电脑上才可以使用的程序特点:不需要联网也可以打开使用部分功能但是现在的情况是许多功能依然需要互联网的支持 代码部分在用户电脑上执 ...

  7. 【noip新手入门向】OpenJudge1.3-14大象喝水

    一.写在前面 我也不知道我为什么要写这个鬼畜的东西←_←才不是为了水blog量什么的(划掉),其实是为了明天给学弟学妹们传教准备. 这道题对完全对c语言没有概念的小萌新们极度友好,可以锻炼小萌新们的代 ...

  8. R之data.table -melt/dcast(数据合并和拆分)

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 30.0px "Helvetica Neue"; color: #323333 } p. ...

  9. CentOS7 基础配置

    Centos 7 部分>>>>>>>>>>>>>>>>>>>>>>& ...

  10. CocoaPods安装第三方出错:XCode7.3

    错误[!] The dependency `Masonry (~> 0.6.1)` is not used in any concrete target. 在之前,我使用的版本是XCode7.0 ...