agc023D - Go Home
题目大意
题解
想了一天结果连边都没有挨到
结论:如果a1>=an,则车一定会先去1,之后从1去往n
证明:n=2时满足,n>2时如果车在n-1~n处,因为a1>=an所以1想的话可以直接消掉n的影响,同时2~n-1也会跟着这么做(其实根据题目的描述来说每个人的选择与本轮其他人的选择无关,但是也可以归纳得到)
如果车在n-1之前,则要么会先走到1,要么变成上面的情况
那么n的时间=1的时间+1n距离,n的人一定会希望1的时间尽量早,所以n会支持1,因此可以视作把n的人搬到1,即a1+=an,然后递归往下做,最后ans加上 n的位置-子问题结束后车的位置
a1<an反之同理
code
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define ll long long
//#define file
using namespace std;
int b[100001],n,i,j,k,l,r,x;
ll a[100001],ans;
int dg(int l,int r)
{
int X;
if (x<b[l]) {ans+=b[r]-x;return b[r];}
if (x>b[r]) {ans+=x-b[l];return b[l];}
if (a[l]>=a[r])
{
a[l]+=a[r];
ans+=b[r]-dg(l,r-1);
return b[r];
}
else
{
a[r]+=a[l];
ans+=dg(l+1,r)-b[l];
return b[l];
}
}
int main()
{
#ifdef file
freopen("agc023d.in","r",stdin);
#endif
scanf("%d%d",&n,&x);
fo(i,1,n) scanf("%lld%d",&b[i],&a[i]);
dg(1,n);
printf("%lld\n",ans);
fclose(stdin);
fclose(stdout);
return 0;
}