抱歉,之前的代码被hack了,我这乌鸦嘴啊……
但是整体思路和优化方式还是莫得问题的,只不过需要再加一些小技巧
如果是之前看过鄙人的不完备题解的话,请点击这里
题意:
一个长度为
n
n
n的空间中,有
k
k
k个空调,第
j
j
j台空调放置在单元格
a
j
(
1
≤
a
j
≤
n
)
a_{j}(1≤a_{j}≤n)
aj(1≤aj≤n)中,温度为
t
j
t_{j}
tj
(
1
≤
j
≤
k
)
(1≤j≤k)
(1≤j≤k),两个或更多的空调不能放在同一个单元(即所有的
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==min(t1+∣a1−i∣,t2+∣a2−i∣,……,tk+∣ak−i∣)(1≤i≤n,1≤j≤k)
对于从 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+∣aj−i∣小于当前单元格 i i i之前的温度 T i T_{i} Ti,则更新
这里我们要注意到非常重要的一点,如果它能带来的影响 t j + ∣ a j − i ∣ t_{j}+\lvert a_{j}-i \rvert tj+∣aj−i∣是比当前单元格 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+∣aj−i∣要小的话,说明第 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+∣ah−i∣≤tj+∣aj−i∣,咱们都列举出来瞅瞅:
-
a j ≤ i ≤ a h a_{j}≤i≤a_{h} aj≤i≤ah 和 a h ≤ i ≤ a j a_{h}≤i≤a_{j} ah≤i≤aj 就不必多说了,一个递增一个递减很明显
-
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} aj≤ah≤i、ah≤aj≤i、i≤aj≤ah 和 i ≤ a h ≤ a j i≤a_{h}≤a_{j} i≤ah≤aj,第 j 、 h j、h j、h两台空调在趋近单元格 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+∣ah−i∣≤tj+∣aj−i∣也就恒成立了
就这样遍历 k k k个冰箱所造成的影响然后最后输出从 1 1 1到 n n n的每个单元格的最终温度即可
时间复杂度:
理论上来说,读入后直接遍历
k
k
k个冰箱最差的时间复杂度应该为为
O
(
k
∗
n
)
O(k*n)
O(k∗n),意思是每一个冰箱对于从
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}) ah(th>tj)时,所造成的影响 t j + ∣ a j − i ∣ t_{j}+\lvert a_{j}-i \rvert tj+∣aj−i∣也会小于 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;
}