给定一个长度为\(n\)的一维区间,区间里有\(k\)个空调,不存在重合的情况。每个空调能在其位置\(a\)上造成温度\(t\),每远离该位置\(1\)个单位距离,温度上升\(1\)。每个点的温度是所有的空调在这里造成的温度的最小值。
易知往右边的位置,是左边的空调的最小值加上\(1\),右边的空调最小值减去\(1\),因此我们考虑:
综上所述,我们可以使用单调队列维护所有空调的最小值,然后从左到右遍历每一个位置,遇到一个空调,就将其从队列中弹出,并维护左边的最小值,答案就是左边和右边的值的最小值。
int n, k; struct CON { int a, t; bool operator < (const CON &x) {return a < x.a;} }c[N]; PII b[N]; pair<bool, int> st[N]; int res[N]; int q[N]; int main() { int T; cin >> T; while (T -- ) { cin >> n >> k; for (int i = 1; i <= k; i ++ ) cin >> c[i].a; for (int i = 1; i <= k; i ++ ) cin >> c[i].t; sort(c + 1, c + 1 + k); for (int i = 1; i <= k; i ++ ) st[c[i].a] = {true, i}; int l = 0x3f3f3f3f; int hh = 0, tt = -1; for (int i = 1; i <= k; i ++ ) { while (hh <= tt && c[q[tt]].t + c[q[tt]].a - 1 > c[i].t + c[i].a - 1) tt -- ; q[++ tt] = i; } for (int i = 1; i <= n; i ++ ) { if (st[i].x) { int id = st[i].y; l = min(l, c[id].t + c[id].a - i); if (id >= q[hh]) hh ++ ; st[i].x = false; } if (hh <= tt) { int id = q[hh]; int r = c[id].t + c[id].a - i; res[i] = min(l, r); } else res[i] = l; l ++ ; } for (int i = 1; i <= n; i ++ ) cout << res[i] << ' '; cout << endl; } return 0; }