又被神题制裁了。想到了一个策略,结果和正解有偏差,交上去过了一半的点,还以为是写挂了看了半天。。。
考虑
1
1
1号点和
n
n
n号点,一般的,假设
X
1
<
S
X_1<S
X1<S,
X
n
>
S
X_n>S
Xn>S。不妨设
P
1
<
P
n
P_1<P_n
P1<Pn,这样我们发现对于
1
1
1来说,它一定会在
n
n
n之后被送回家,它肯定希望
n
n
n尽早被送回家,然后车就会直接开到
1
1
1,因此它会跟票
n
n
n(这里我搞成
1
1
1会投向右的票,其实是错的,因为
n
n
n有可能投向左的,但是
1
1
1投的永远跟
n
n
n一致),于是我们可以让
P
n
P_n
Pn加上
P
1
P_1
P1,把
1
1
1删掉再补上最后的贡献。
类似这样做就OK了,时间复杂度
O
(
n
)
\mathcal O(n)
O(n)。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[100005],b[100005];
int q[100005];
int main() {
int n,s;
scanf("%d%d",&n,&s);
int id=0;
for(int i=1;i<=n;i++) {
scanf("%lld%lld",&a[i],&b[i]);
if (a[i]<s) id=i;
}
int cnt=0,l=1,r=n;
while ((l<=id)^(r<=id))
if (b[l]>=b[r]) {
q[++cnt]=a[r];
b[l]+=b[r];
r--;
}
else {
q[++cnt]=a[l];
b[r]+=b[l];
l++;
}
if (r<=id) {
for(int i=l;i<=r;i++) q[++cnt]=a[i];
}
else {
for(int i=r;i>=l;i--) q[++cnt]=a[i];
}
q[cnt+1]=s;
ll ans=0;
for(int i=1;i<=cnt;i++) ans+=abs(q[i]-q[i+1]);
printf("%lld\n",ans);
return 0;
}