ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-07-30 19:04:07  阅读:126  来源: 互联网

标签:飞机 QAQ int 题解 maxn 廊桥 CSP define


传送门QAQ

Preface

这道题当时在考场上就大致想清楚了做法,考场下写了个巨丑无比的树状数组+二分+线段树+ STL set我都不知道我是怎么写下来的

现在回看这道题,发现真的不难QAQ,当时太菜了。当然,现在也菜

Analysis

注意:这道题的“先到先得”是让我们按照飞机到达的时间升序排序。

(我考场上就因为这个没搞出来正解,好像帆巨也因为这个爆零了QAQ)

首先发现,国内和国外可以分开处理,最后枚举统计。

这就要求我们对国内和国外求出分配 \(i\) 个廊桥时的飞机数。

观察到一个性质:如果分配 \(i\) 个廊桥时飞机 \(j\) 有位置,则分配 \(i+1\) 个廊桥时飞机仍有位置。

观察一下样例的那张图,手玩一下样例,不难发现这个性质。

那么我们只需要求出每个飞机 \(j\) 所需的最小廊桥数,再用前缀和统计即可。

不妨把廊桥按照 \(1\sim m\) 标号,用两个优先队列维护空闲和非空闲的廊桥,设为 \(q_1,q_2\)。

当遍历到一个新飞机,弹出 \(q_2\) 中飞走的飞机,把这些廊桥放入 \(q_1\),再从 \(q_1\) 取出最小的廊桥。

国内国外的飞机都处理一遍,用前缀和维护一下,然后枚举即可。

时间复杂度 \(O(N\log N)\)。

Code

// Problem: #3542. 「CSP-S 2021」廊桥分配
// Contest: LibreOJ
// URL: https://loj.ac/p/3542
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define mp make_pair
#define fir first
#define sec second
using namespace std;
const int maxn = 1e5 + 5;
typedef pair<int,int> pii;
struct node {
	int x,y;
	node() {
		x = y = 0;
	}
}a[maxn],b[maxn];
int n,m,k;
int sum1[maxn],sum2[maxn];
priority_queue<pii,vector<pii>,greater<pii> > q;
priority_queue<int,vector<int>,greater<int> > s;
int main() {
	freopen("airport.in","r",stdin);
	freopen("airport.out","w",stdout);
	scanf("%d %d %d",&n,&m,&k);
	for(int i = 1;i <= m;++ i) {
		scanf("%d %d",&a[i].x,&a[i].y);
	}
	sort(a + 1 , a + 1 + m , [&](const node& p,const node& q) {
		return p.x < q.x;
	});
	for(int i = 1;i <= k;++ i) {
		scanf("%d %d",&b[i].x,&b[i].y);
	}
	sort(b + 1 , b + 1 + k , [&](const node& p,const node& q) {
		return p.x < q.x;
	});
	while(!q.empty())q.pop();
	while(!s.empty())s.pop();
	for(int i = 1;i <= m;++ i)s.push(i);
	for(int i = 1;i <= m;++ i) {
		for(;!q.empty()&&q.top().fir < a[i].x;q.pop())s.push(q.top().sec);
		int ans = s.top();
		s.pop();
		++ sum1[ans];
		q.push(mp(a[i].y , ans));
	}
	while(!q.empty())q.pop();
	while(!s.empty())s.pop();
	for(int i = 1;i <= k;++ i)s.push(i);
	for(int i = 1;i <= k;++ i) {
		for(;!q.empty()&&q.top().fir < b[i].x;q.pop())s.push(q.top().sec);
		int ans = s.top();
		s.pop();
		++ sum2[ans];
		q.push(mp(b[i].y , ans));
	}
	for(int i = 1;i <= n;++ i)sum1[i] += sum1[i - 1],sum2[i] += sum2[i - 1];
	int ans = 0;
	for(int i = 0;i <= n;++ i)ans = max(ans , sum1[i] + sum2[n - i]);
	printf("%d\n",ans);
	return 0;
}

完结撒花✿✿ヽ(°▽°)ノ✿

标签:飞机,QAQ,int,题解,maxn,廊桥,CSP,define
来源: https://www.cnblogs.com/663B/p/16535569.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有