思路和各题解类似,但必须加上第17行才对。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 200010;
int T, n;
int l[N], r[N];
LL p[N], s[N], res[N];
struct node
{
LL t, a, b;
bool operator <(const node &x) const
{
if (t != x.t) return t < x.t;
return a < x.a;
}
};
set <node> S;
LL calc(int a, int b)
{
return (p[b] - p[a] + s[a] + s[b] - 1) / (s[a] + s[b]) * 2 - (a & 1);
}
int main()
{
scanf("%d", &T);
while (T -- )
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%lld", &p[i]);
for (int i = 1; i <= n; i ++ ) scanf("%lld", &s[i]);
for (int i = 1; i <= n; i ++ ) l[i] = i - 1, r[i] = i + 1;
for (int i = 1; i < n; i ++ ) S.insert({calc(i, i + 1), i, i + 1});
while (S.size())
{
node tmp = *S.begin(); S.erase(S.begin());
int a = tmp.a, b = tmp.b;
res[a] = res[b] = tmp.t;
if (l[a]) S.erase({calc(l[a], a), l[a], a});
if (r[b] != n + 1) S.erase({calc(b, r[b]), b, r[b]});
if (l[a] && r[b] != n + 1) S.insert({calc(l[a], r[b]), l[a], r[b]});
r[l[a]] = r[b]; l[r[b]] = l[a];
}
for (int i = 1; i <= n; i ++ ) printf("%lld ", res[i]);
printf("\n");
}
return 0;
}
若不加17行,我发现每删去相邻点a, b时, 消除l[a] 和r[b]所需时间有可能小于小于消除a, b的时间。这是为什么呢?有大佬能证明吗?