Codeforces Round #731 (Div. 3) E. Air Conditioners题解(改)

抱歉,之前的代码被hack了,我这乌鸦嘴啊……
之前的题解
但是整体思路和优化方式还是莫得问题的,只不过需要再加一些小技巧
如果是之前看过鄙人的不完备题解的话,请点击这里


E. Air Conditioners

题意
一个长度为 n n n的空间中,有 k k k个空调,第 j j j台空调放置在单元格 a j ( 1 ≤ a j ≤ n ) a_{j}(1≤a_{j}≤n) aj1ajn中,温度为 t j t_{j} tj ( 1 ≤ j ≤ k ) (1≤j≤k) 1jk,两个或更多的空调不能放在同一个单元(即所有的 a j a_{j} aj是不同的)

每一个空调都能影响整个空间的温度,即 T i = = m i n ( t 1 + ∣ a 1 − i ∣ , t 2 + ∣ a 2 − i ∣ , … … , t k + ∣ a k − i ∣ ) ( 1 ≤ i ≤ n , 1 ≤ j ≤ k ) T_{i}==min(t_{1}+\lvert a_{1}-i \rvert,t_{2}+\lvert a_{2}-i \rvert,……,t_{k}+\lvert a_{k}-i \rvert)(1≤i≤n,1≤j≤k) Ti==mint1+a1it2+a2itk+aki1in1jk

对于从 1 1 1 n n n的每个单元格,求它的温度 T T T

思路
理解题意之后,思路很明确,求每一个空调对于所有 n n n个单元格的影响,然后求最小值

瞅瞅数据大小,坑也很明确,你敢暴力它就敢TLE

一步一步来,对于每一个电冰箱 j j j,从它所在的单元格 a j a_{j} aj分别向左/右遍历,如果它能带来的影响 t j + ∣ a j − i ∣ t_{j}+\lvert a_{j}-i \rvert tj+aji小于当前单元格 i i i之前的温度 T i T_{i} Ti,则更新

这里我们要注意到非常重要的一点,如果它能带来的影响 t j + ∣ a j − i ∣ t_{j}+\lvert a_{j}-i \rvert tj+aji是比当前单元格 i i i之前的温度 T i T_{i} Ti要大的,那我们是不需要继续向左/右遍历继续遍历下去的

因为当前的 T i T_{i} Ti t j + ∣ a j − i ∣ t_{j}+\lvert a_{j}-i \rvert tj+aji要小的话,说明第 i i i个单元格是之前已经被其他空调 h h h更新过的

而无论之前的空调的位置 a h a_{h} ah、第 i i i个单元格的位置 i i i、第 j j j个空调的位置 a j a_{j} aj是怎样的位置关系,在 i i i点之后第 h h h个空调所带来的影响都比第 j j j个空调更优,即 t h + ∣ a h − i ∣ ≤ t j + ∣ a j − i ∣ t_{h}+\lvert a_{h}-i \rvert≤t_{j}+\lvert a_{j}-i \rvert th+ahitj+aji,咱们都列举出来瞅瞅:

  • a j ≤ i ≤ a h a_{j}≤i≤a_{h} ajiah a h ≤ i ≤ a j a_{h}≤i≤a_{j} ahiaj 就不必多说了,一个递增一个递减很明显

  • a j ≤ a h ≤ i 、 a h ≤ a j ≤ i 、 i ≤ a j ≤ a h a_{j}≤a_{h}≤i、a_{h}≤a_{j}≤i、i≤a_{j}≤a_{h} ajahiahajiiajah i ≤ a h ≤ a j i≤a_{h}≤a_{j} iahaj,第 j 、 h j、h jh两台空调在趋近单元格 i i i时,所造成的影响的变化趋势与变化幅度都相同,即它们所造成的影响的绝对值之差是一个恒定值,自然 t h + ∣ a h − i ∣ ≤ t j + ∣ a j − i ∣ t_{h}+\lvert a_{h}-i \rvert≤t_{j}+\lvert a_{j}-i \rvert th+ahitj+aji也就恒成立了

就这样遍历 k k k个冰箱所造成的影响然后最后输出从 1 1 1 n n n的每个单元格的最终温度即可

时间复杂度
理论上来说,读入后直接遍历 k k k个冰箱最差的时间复杂度应该为为 O ( k ∗ n ) O(k*n) O(kn),意思是每一个冰箱对于从 1 1 1 n n n的每个单元格在所造成的影响均优于前一个,但是可能是数据比较水吧,竟然让我AC了……

优化方式也有,就是读入 k k k个冰箱的信息之后依照它们的初始温度 t j t_{j} tj进行升序排序,这样比降序排序,也就是最差情况快了将近 30 % 30\% 30%
时间复杂度

优化2.0:

ps:这次hack的人也忒疯狂了……
首先是上面的排序优化方式是可行的,但是还不够

看到 T e s t 20 Test20 Test20之后的测试数据可以看出,近乎每一个单元格都有冰箱,并且 t j t_{j} tj都十分接近,就算用排序去优化,也会出现对于从 1 1 1 n n n的每个单元格遍历整整 k k k的超时情况

那么我们可以在排序优化的基础上再搞些花活,在读入第 j j j个冰箱的信息时,同时更新 T a j = = t j T_{a_{j}}==t_{j} Taj==tj,因为 a j a_{j} aj及其附近的点绝大部分都是由第 j j j个冰箱所造成的影响为最小值,那么 t j t_{j} tj较小的冰箱在遍历到离 a j a_{j} aj较远的地方,如 a h ( t h > t j ) a_{h}(t_{h}>t_{j}) ahth>tj时,所造成的影响 t j + ∣ a j − i ∣ t_{j}+\lvert a_{j}-i \rvert tj+aji也会小于 t h t_{h} th,因此,第 j j j个空调遍历到 a h a_{h} ah时,就应当停止了

对于看过之前不完备题解的朋友们再说一声抱歉,真的对不起,下次一定三思之后再发题解……

#include<bits/stdc++.h>
using namespace std;
int n, k;
int s[300010];
pair<int, int> q[300010];

bool cmp1(pair<int, int> a, pair<int, int> b) {
	return a.second < b.second;
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		scanf("%d %d", &n, &k);
		int a, res;
		memset(s, 0x3f3f3f3f, sizeof s);
		for (int i = 1; i <= k; i++)
			scanf("%d", &q[i].first);
		for (int i = 1; i <= k; i++) {
			scanf("%d", &q[i].second);
			s[q[i].first] = q[i].second;
			//加上这一步
		}

		sort(q + 1, q + 1 + k, cmp1);
		for (int i = 1; i <= k; i++) {
			int l = q[i].first - 1, r = q[i].first + 1, j = q[i].first;
			int cnt = q[i].second;
			s[j] = min(s[j], cnt);
			while (l >= 1 && s[l] > cnt + j - l) {
				s[l] = cnt + j - l;
				l--;
			}

			while (r <= n && s[r] > cnt - j + r ) {
				s[r] = cnt - j + r;
				r++;
			}
		}

		for (int i = 1; i <= n; i++)
			printf("%d ", s[i]);
		printf("\n");
	}
	return 0;
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值