jzoj7197「JOI 2020 Final」只不过是长的领带(两种做法)

Posted SSL_ZZL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jzoj7197「JOI 2020 Final」只不过是长的领带(两种做法)相关的知识,希望对你有一定的参考价值。

题面

Description

在这里插入图片描述

Input

在这里插入图片描述

Output

在这里插入图片描述

Sample Input

样例 1 输入:

3
4 3 7 6
2 6 4

样例 2 输入:

5
4 7 9 10 11 12
3 5 7 9 11

Sample Output

样例 1 输出:

2 2 1 1

在这里插入图片描述

样例 2 输出:

4 4 3 2 2 2

Data Constraint

在这里插入图片描述


解题思路

虽不会证明,但很容易想到n^2的贪心
排个序,然后一一对应,能选就选
在这里插入图片描述

很容易发现,当不能选的领带向右时(到第四个领带),最左边的两条选择是不变的,不需要重新计算
做一个预处理,把左边的的直线预处理出来,f[i]表示第i个领带不能选时,左边1~i-1的最大值
于是又很容易想到,右边也可以做这么一个斜线的预处理(考场上打错了还以为不行)

考场上打的事不做后面的斜线预处理,从m倒着求答案
每次都会有三个板块的答案,三个答案再取max就好了
在这里插入图片描述

#tips
排完序记得把答案离线时对好位置
(听题的时候听到有人说,样例特坑,没有对位置也能过然后就忘了)


Code

两个预处理

#include <algorithm>
#include <iostream>
#include <cstdio>

using namespace std;

struct DT{
	int s, i;
}a[210000];
int n, m, b[210000], ans[210000], qm[210000], hm[210000];

bool cmp(const DT&k, const DT&l) {return k.s < l.s;}

int main() {
	scanf("%d", &n);
	m = n + 1;
	for(int i = 1; i <= m; i++) {
		scanf("%d", &a[i].s);
		a[i].i = i;
	}
	sort(a + 1, a + 1 + m, cmp);
	for(int i = 1; i <= n; i++)
		scanf("%d", &b[i]);
	sort(b + 1, b + 1 + n);
	for(int i = 2; i <= m; i++)
		qm[i] = max(qm[i - 1], max(a[i - 1].s - b[i - 1], 0));
	for(int i = m - 1; i; i--)
		hm[i] = max(hm[i + 1], max(a[i + 1].s - b[i], 0));
	for(int i = m; i; i--)
		ans[a[i].i] = max(qm[i], hm[i]);
	for(int i = 1; i <= m; i++)
		printf("%d ", ans[i]);
}

一个预处理

#include <algorithm>
#include <iostream>
#include <cstdio>

using namespace std;

struct DT{
	int s, i;
}a[210000];
int n, m, b[210000], ans[210000], qm[210000];

bool cmp(const DT&k, const DT&l) {return k.s < l.s;}

int main() {
	scanf("%d", &n);
	m = n + 1;
	for(int i = 1; i <= m; i++) {
		scanf("%d", &a[i].s);
		a[i].i = i;
	}
	sort(a + 1, a + 1 + m, cmp);
	for(int i = 1; i <= n; i++)
		scanf("%d", &b[i]);
	sort(b + 1, b + 1 + n);
	for(int i = 2; i <= m; i++)
		qm[i] = max(qm[i - 1], max(a[i - 1].s - b[i - 1], 0));
	for(int i = m; i; i--){
		ans[a[i].i] = max(qm[i], max(a[i + 1].s - b[i], 0));
		ans[a[i].i] = max(ans[a[i].i], ans[a[i + 1].i]);
	}
	for(int i = 1; i <= m; i++)
		printf("%d ", ans[i]);
}

以上是关于jzoj7197「JOI 2020 Final」只不过是长的领带(两种做法)的主要内容,如果未能解决你的问题,请参考以下文章

JOI 2020 Final 火灾

[JOI 2014 Final]IOI 馒头

2018.9.20JOI 2017 Final T2「準急電車 / Semiexpress」

年轮蛋糕JOI2014Final

#3468. 「JOI 2021 Final」有趣的家庭菜园 4(双指针&差分)

[JOI 2015 Final]分蛋糕 2