Atcoder agc023D

63 篇文章 0 订阅
27 篇文章 1 订阅

又被神题制裁了。想到了一个策略,结果和正解有偏差,交上去过了一半的点,还以为是写挂了看了半天。。。
考虑 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值