题目描述请移步 https://www.luogu.com.cn/problem/P7913

  • 题目简述

有一座机场,分为国际区和国外区,机场共有n个廊桥,国内国际分别有m1,m2架飞机,给定每架飞机抵达时刻a[i]、离开时刻b[i]

对于每架飞机,若该区仍有廊桥空闲,就必须停靠在廊桥,否则停靠远机位(数量足够)

求将n个廊桥分配给国内区和国际区,停靠廊桥的飞机最多有多少架

  • 题目分析

首先注意到飞机是有后效性的,先到达的飞机可能会占用一个廊桥直到它离开,因此需要对每架飞机按到达时间进行排序

遍历每架飞机复杂度为 O(m1+m2) ,而 m1+m2 就达到了 10^5 级别

因此累加贡献部分的复杂度须为 O(log n)

  • 解题思路

发现对于每架飞机,如果它在有 x 个廊桥时停靠廊桥,那么有 x+1 个廊桥时它必定停靠廊桥

点击查看证明
假设 x=2 ,为方便,第i架飞机用 p[i] 来表示

不管数据具体是什么,这两个廊桥的使用必定与下图相似

廊桥1:p[1] --> p[3] -> p[4] ---------> p[9]
廊桥2:p[2] ---------------> p[7]
(后面 “上一架飞机” 意为使用同一廊桥的上一架飞机) 每架飞机后面跟的都是首个到达时间比它离开时间晚的飞机(不考虑其他廊桥的占用) 若第 i 架飞机在两个廊桥时停靠廊桥,而三个廊桥时不停靠廊桥,则只可能其上一架飞机未停靠廊桥 以此类推,只有第 i 架飞机上一架的上一架... 即首个停靠原第 i 架飞机所停靠的廊桥的飞机未停靠廊桥,才可能成立 而新设一个廊桥并不影响原廊桥第一架停靠的飞机,因此这种情况不可能发生

因此,每架飞机对答案的贡献,是一个 min_can~n 的区间(令 min_can 为最小的可让这架飞机停靠廊桥的廊桥数量)

考虑使用线段树、树状数组等 log n 级别的结构来解决

这是我们只需维护每架飞机的 "min_can" 就行了,这里分两种情况讨论

1.这架飞机(p[i])到达时有飞机(p[j])离开了,那么 min_can[x]=min_can[j]

2.这架飞机到达时没有飞机离开,则 min_can[x]=目前所有没离开的飞机的数量

要注意的是,一架飞机到达时可能有多架飞机离开,那么它之后的几架飞机仍可以从情况1转移

  • 代码实现
#include <iostream>
#include <utility>
#include <algorithm>
#include <cstring>
#include <queue>
#define int long long
using namespace std;
const int MAX=1e5+7;
int n,m1,m2;
pair <int,int> p1[MAX],p2[MAX];//飞机
//priority_queue升序
priority_queue <pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q1,q2;//<离开时间,第几架>
priority_queue <int,vector<int>,greater<int> > mc1,mc2;//所有离开的飞机,维护并找到最小的min_can
int min_can1[MAX],min_can2[MAX];//最少多少个廊桥才能使第i架飞机降落在廊桥
int tr1[MAX],tr2[MAX];//树状数组
int lowbit(int x){
return x&-x;
}
void add1(int pos){
for(int i=pos;i<=m1;i+=lowbit(i)){
tr1[i]++;
}
}
void add2(int pos){
for(int i=pos;i<=m2;i+=lowbit(i)){
tr2[i]++;
}
}
int query1(int pos){
int res=0;
for(int i=pos;i>=1;i-=lowbit(i)){
res+=tr1[i];
}
return res;
}
int query2(int pos){
int res=0;
for(int i=pos;i>=1;i-=lowbit(i)){
res+=tr2[i];
}
return res;
}
signed main(){
cin>>n>>m1>>m2;
n=min(n,m1+m2);
for(int i=1;i<=m1;i++){
cin>>p1[i].first>>p1[i].second;
}
for(int i=1;i<=m2;i++){
cin>>p2[i].first>>p2[i].second;
}
sort(p1+1,p1+m1+1);
sort(p2+1,p2+m2+1);//按first升序
memset(min_can1,0x3f,sizeof(min_can1));
memset(min_can2,0x3f,sizeof(min_can2));//初始化极大值
for(int i=1;i<=m1;i++){
while(!q1.empty()&&q1.top().first<p1[i].first){
mc1.push(min_can1[q1.top().second]);//将离开的飞机的min_can值推入另一个优先队列
q1.pop();
}
q1.push(make_pair(p1[i].second,i));
if(!mc1.empty()){//有未利用的离开的飞机
add1(mc1.top());
min_can1[i]=mc1.top();
mc1.pop();
}else{
add1(q1.size());//未离开的飞机的数量
min_can1[i]=q1.size();//更改min_can的值
}
}
for(int i=1;i<=m2;i++){//同上
while(!q2.empty()&&q2.top().first<p2[i].first){
mc2.push(min_can2[q2.top().second]);
q2.pop();
}
q2.push(make_pair(p2[i].second,i));
if(!mc2.empty()){
add2(mc2.top());
min_can2[i]=mc2.top();
mc2.pop();
}else{
add2(q2.size());
min_can2[i]=q2.size();
}
}
int ans=-1;
for(int i=0;i<=n;i++){
ans=max(ans,query1(i)+query2(n-i));//合并答案
}
cout<<ans;
}

完结撒花qwq

洛谷 P7913 [CSP-S 2021] 廊桥分配 题解的更多相关文章

  1. [CSP-S 2021] 廊桥分配 题解

    写篇题解来纪念我炸掉的CSP 唯一会做的题代码写挂了(痛苦面具 思路 我看到这道题第一眼想到的是线段树,感觉可以用线段树维护飞机入站到出战的这段时间,想了半天想不到代码怎么写. 国内机场与国外机场要分 ...

  2. 【洛谷P3369】【模板】普通平衡树题解

    [洛谷P3369][模板]普通平衡树题解 题目链接 题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3 ...

  3. 洛谷 P1992 不想兜圈的老爷爷 题解

    洛谷 P1992 不想兜圈的老爷爷 题解 题目描述 一位年过古稀的老爷爷在乡间行走 而他不想兜圈子 因为那会使他昏沉 偶然路过小A发扬助人为乐优良传统 带上地图 想知道路况是否一定使他清醒 usqwe ...

  4. [CSP-S2021] 廊桥分配

    链接: P7913 题意: 有 \(m_1\) 架飞机和 \(m_2\) 架飞机停在两个机场,每架飞机有到达和离开的时间,要将 \(n\) 个廊桥分给两个机场,每个廊桥同一时刻只能停一架飞机,需要最大 ...

  5. BZOJ5285 & 洛谷4424 & UOJ384:[HNOI/AHOI2018]寻宝游戏——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5285 https://www.luogu.org/problemnew/show/P4424 ht ...

  6. 洛谷p3384【模板】树链剖分题解

    洛谷p3384 [模板]树链剖分错误记录 首先感谢\(lfd\)在课上调了出来\(Orz\) \(1\).以后少写全局变量 \(2\).线段树递归的时候最好把左右区间一起传 \(3\).写\(dfs\ ...

  7. 洛谷 P1789 【Mc生存】插火把 题解

    P1789 [Mc生存]插火把 题目背景 初一党应该都知道...... 题目描述 话说有一天 linyorson 在"我的世界"开了一个 \(n\times n(n\le 100) ...

  8. 洛谷P8508 做不完的作业【题解】

    事先声明 此题解为一篇洛谷题解的详细补充,这里(我才不告诉你我这道题想了好久) 题目大意 有 \(n\) 个任务,记作 \(t\) 数组,由于主人公很懒,所以他每天都要睡觉,每一天都有 \(x\) 小 ...

  9. 洛谷P1066 2^k进制数(题解)(递推版)

    https://www.luogu.org/problemnew/show/P1066(题目传送) (题解)https://www.luogu.org/problemnew/solution/P106 ...

  10. 洛谷P1373小a和uim大逃离题解

    题目 这个题好坑啊,首先是他会卡空间,然后我们就只能把一种比较好理解的状态给舍弃,因为空间开不下,然而采用一种难理解的状态就是\(dp[i][j][l][0/1]\)表示\(i\),\(j\)位置,两 ...

随机推荐

  1. MobiSys'2022 CoDL论文详解

    算子切分 在了解算子切分前,先了解一下卷积的运算过程,作者将算子切分分为了两个维度的切分:OC维度和H维度,没有W维度可能与数据在内存中的存储方式有关. OC维度切分 卷积就是OC数量个kernel_ ...

  2. 【EI期刊收录】第六届材料化学与复合材料国际学术会议(MCCM 2025)

    [会议亮点] 1. 前五届均已见刊检索 2. 支持线上参会,线上做口头报告,线上做海报展示 3. 广东工业大学主办-已确定线下 4. 本届EI期刊合作,并延续JPCS同步收录,双出版,多种选择 第六届 ...

  3. 故障处理:Oracle一体机磁盘故障时磁盘组重平衡失败的故障处理

    最近半个月遇到有两个客户的Oracle Exadata一体机出现物理磁盘的损坏,一个客户是机械磁盘.一个客户是FLASH磁盘.很巧的是这两个客户他们的日常运维过程中都是只看物理服务器的故障信号灯.但是 ...

  4. SQL使用行锁

    https://www.cnblogs.com/wolfocme110/p/14727133.html 行锁使用需要注意 1.ROWLOCK行级锁确保在用户取得被更新的行,到该行进行更新,这段时间内不 ...

  5. C# 遍历Enum( 枚举)

    Type enumType = typeof(Domain.Models.Entitys.PermissionEntity.PermissionTypeEnum);                   ...

  6. vue常用配置

    修改titlevue.config.js chainWebpack: config =>{ config.plugin('html') .tap(args => { args[0].tit ...

  7. CF1923E Count Paths 题解

    CF1923E Count Paths 点分治模板题. 假设当前处理的树根为 \(x\),我们考虑如何统计经过点 \(x\) 的合法路径. \(1\):存在一个与 \(x\) 颜色相同的点,且这个点到 ...

  8. C2. Pokémon Army (hard version) CF #672

    题意:给你一个序列,让你任意选出一个子序列,使得奇数位和减去偶数位和最大.同时有q个询问,输出每次交换完a[l]和a[r]后的上述最大值. 思路:首先肯定可以确定选出来的子序列长度为奇数,因为偶数位只 ...

  9. Codeforces Round #665 (Div. 2) ABC题解

    A. Distance and Axis 题意:给出OX坐标上OA的长度,每次可以将A移动一个单位,问最少多少次可以找出坐标B的整数解使得 | OB - AB | = k. 思路:分类讨论. 1.若B ...

  10. 日事清助力制造业IPD全生命周期管理:从开发流程到持续优化的跨部门协作实践

    一.先聊聊IPD,它到底是什么 在竞争激烈的市场中,产品的快速.精准开发是企业致胜的关键.而为了确保新产品能够顺利从概念到落地,越来越多的企业采用集成产品开发(IPD, Integrated Prod ...