51Nod 欢乐手速场1 A Pinball[DP 线段树]

第一行两个数,m和n。m<=100000,2<=n<=1000000000
接下来m行,第i+1行描述第i个漏斗的属性,Ai,Bi,Ci,Di (1<=Ai<=Ci<=Bi<=n, 1<=Di<=1000000000)。
若不存在一种方案能满足条件则输出-1,否则输出最小花费
5 6
3 5 4 8
1 4 3 5
4 6 5 7
5 6 5 3
3 5 4 12
20
最后一定经过同一个漏斗
枚举最后经过哪个漏斗,然后求出第1列和第n列到达这个漏斗的最小花费就好了
考虑DP L[i]和R[i]
L[i]表示从1下落使用漏斗i到达C[i]的最小话费 L[i]=min{L[j] : A[i]<=C[j]<=B[i]}+D[i]}
这种带修改的RMQ问题用个线段树就好了
当然要离散化列啦
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define lson x<<1,l,mid
#define rson x<<1|1,mid+1,r
#define lc x<<1
#define rc x<<1|1
typedef long long ll;
const int N=1e5+,M=3e5+;
const ll INF=1e18;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,m,a[N],b[N],c[N],d[N];
int mp[M];
void iniMP(){
sort(mp+,mp++mp[]);
int p=;mp[++p]=mp[];
for(int i=;i<=mp[];i++) if(mp[i]!=mp[i-]) mp[++p]=mp[i];
mp[]=p;
}
int Bin(int v){
int l=,r=mp[];
while(l<=r){
int mid=(l+r)>>;
if(mp[mid]==v) return mid;
else if(v<mp[mid]) r=mid-;
else l=mid+;
}
return ;
}
ll t[M<<];
void build(int x,int l,int r){
if(l==r) t[x]=INF;
else{
int mid=(l+r)>>;
build(lson);
build(rson);
t[x]=min(t[lc],t[rc]);
}
}
void segCha(int x,int l,int r,int p,ll v){
if(l==r) t[x]=min(t[x],v);//!!!
else{
int mid=(l+r)>>;
if(p<=mid) segCha(lson,p,v);
else segCha(rson,p,v);
t[x]=min(t[lc],t[rc]);
}
}
ll segMin(int x,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) return t[x];
else{
ll re=INF;
int mid=(l+r)>>;
if(ql<=mid) re=min(re,segMin(lson,ql,qr));
if(mid<qr) re=min(re,segMin(rson,ql,qr));
return re;
}
}
ll L[N],R[N];
void solve(){
build(,,mp[]);
segCha(,,mp[],,);
// printf("check %d %d\n",segMin(1,1,mp[0],2,5),segMin(1,1,mp[0],1,5));
for(int i=;i<=n;i++){
L[i]=segMin(,,mp[],a[i],b[i])+d[i];
segCha(,,mp[],c[i],L[i]);
//printf("L %d %d\n",i,L[i]);
} build(,,mp[]);
segCha(,,mp[],mp[],);
for(int i=;i<=n;i++){
R[i]=segMin(,,mp[],a[i],b[i])+d[i];
segCha(,,mp[],c[i],R[i]);
//printf("R %d %d\n",i,R[i]);
} ll ans=INF;
for(int i=;i<=n;i++) ans=min(ans,L[i]+R[i]-d[i]);
if(ans<INF) printf("%lld",ans);
else puts("-1");
}
int main(){
// freopen("in.txt","r",stdin);
n=read();m=read();
mp[++mp[]]=;mp[++mp[]]=m;
for(int i=;i<=n;i++){
mp[++mp[]]=a[i]=read();
mp[++mp[]]=b[i]=read();
mp[++mp[]]=c[i]=read();
d[i]=read();
}
iniMP();
//for(int i=1;i<=mp[0];i++) printf("mp %d %d\n",i,mp[i]);
for(int i=;i<=n;i++) a[i]=Bin(a[i]),b[i]=Bin(b[i]),c[i]=Bin(c[i]);
solve();
}
51Nod 欢乐手速场1 A Pinball[DP 线段树]的更多相关文章
- 51Nod 欢乐手速场1 C 开心的小Q[莫比乌斯函数]
开心的小Q tangjz (命题人) quailty (测试) 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 如果一个数字存在一个约数是完全平方数,那么小Q就认为这个数是有趣的 ...
- 51Nod 欢乐手速场1 B 序列变换[容斥原理 莫比乌斯函数]
序列变换 alpq654321 (命题人) 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 lyk有两序列a和b. lyk想知道存在多少对x,y,满足以下两个条件. 1:gcd( ...
- 51nod 1781 Pinball(线段树)
题面 Pinball的游戏界面由m+2行.n列组成.第一行在顶端.一个球会从第一行的某一列出发,开始垂直下落,界面上有一些漏斗,一共有m个漏斗分别放在第2~m+1行,第i个漏斗的作用是把经过第i+1行 ...
- 2019牛客多校第八场 F题 Flowers 计算几何+线段树
2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...
- 51nod“省选”模测第二场 C 小朋友的笑话(线段树 set)
题意 题目链接 Sol 直接拿set维护\(li\)连续段.因为set内的区间互不相交,而且每个线段会被至多加入删除一次,所以复杂度是对的. #include<bits/stdc++.h> ...
- 2018牛客网暑假ACM多校训练赛(第六场)I Team Rocket 线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round6-I.html 题目传送门 - https://www.no ...
- 牛客多校第四场 J.Hash Function(线段树优化建图+拓扑排序)
题目传送门:https://www.nowcoder.com/acm/contest/142/J 题意:给一个hash table,求出字典序最小的插入序列,或者判断不合法. 分析: eg.对于序列{ ...
- hdu 5316 Magician(2015多校第三场第1题)线段树单点更新+区间合并
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5316 题意:给你n个点,m个操作,每次操作有3个整数t,a,b,t表示操作类型,当t=1时讲a点的值改 ...
- 51nod 1766 树上的最远点对(线段树)
像树的直径一样,两个集合的最长路也是由两个集合内部的最长路的两个端点组成的,于是我们知道了两个集合的最长路,枚举一下两两端点算出答案就可以合并了,所以就可以用线段树维护一个区间里的最长路了. #inc ...
随机推荐
- PHPStudy+PHPStorm下配置隐藏项目入口文件
img { max-width: 100% } 默认情况下项目入口文件是站点根目录下index.php文件,一般程序启动时通过这个文件,定义文件路径,配置重要节点(比如是否开启调试模式),注册路由等, ...
- [OpenCV学习笔记1][OpenCV基本数据类型]
CvPoint基于二维整形坐标轴的点typedef struct CvPoint{int x; /* X 坐标, 通常以 0 为基点 */int y; /* y 坐标,通常以 0 为基点 */}CvP ...
- 程序员之殇 —— (The Beginning of the End)噩梦、崩坏
Look at all those faces out there (当我环视周遭的一张张脸孔) We are so different(我们是如此的不同) But we have one thing ...
- java如何获取一个对象的大小
When---什么时候需要知道对象的内存大小 在内存足够用的情况下我们是不需要考虑java中一个对象所占内存大小的.但当一个系统的内存有限,或者某块程序代码允许使用的内存大小有限制,又或者设计一个缓存 ...
- 阿里巴巴Java开发手册评
2016年底的时候阿里巴巴公开了其在内部使用的Java编程规范.随后进行了几次版本修订,目前的版本为v1.0.2版.下载地址可以在其官方社区-云栖社区https://yq.aliyun.com/art ...
- 风险案例-28期-项目Leader与团队成员缺乏沟通,问题响应度较慢导致团队士气低落,工作效率低
典型案例: A公司某C类项目目前进入开发高峰期,项目组的三个leader预计在项目的实际task投入占比为70%,剩30%工作时间用于指导组员进行作业实施并担当部分管理工作.从项目实施过程中发现Lea ...
- salesforce零基础学习(八十一)更改标准字段的label名称(Admin)
我们在开发中往往需要考虑国际化功能,salesforce 提供了国际化功能,在search部分搜索translate,便可以找到translate部分,从而对需要的进行translate.比如pick ...
- python_判断变量类型
需求: 已知有一个变量,我想对他进行预处理判断,如果这个变量是字符串,则在字符串后面加上后缀'_str',如果整形就让其加5,还比如我要求这个变量是整形或者字符串,都行 如何做? #!/usr/bin ...
- Java中Unsafe类详解
http://www.cnblogs.com/mickole/articles/3757278.html Java不能直接访问操作系统底层,而是通过本地方法来访问.Unsafe类提供了硬件级别的原子操 ...
- 转-Determining whether a Computer Needs to be Rebooted
1 如何检查机器是否因为装了Windows更新而需要重新启动 2 Determining whether a Computer Needs to be Rebooted 3 How can I tel ...
