题目大意
题解
很快想出来了,但细节挺多
可以发现答案是2L的倍数,每个数与T和X有关,和T的具体值关系不大
先把T模2L,将点分成四类,从右往左下车后能/否往右,从左往右下车后能/否往左,全否称为0,全是称为1,从右往左称为左,从左往右称为右
可以发现不存在先左后右的情况,因为一个左意味着x>L-x,右意味着x<L-x,矛盾
也就是没有在左右之间反复横跳的情况,只会在左/右和1之间横跳
于是扫过去判断,如果走了一个左/右最好能带走一个1,最后答案加上剩余1的个数再补成偶数
还要根据结尾讨论,如果结尾是0则一定要走到结尾再折返,否则可能可以通过1来折返
如果结尾是右的话可以通过右折返,并且这次折返带不走1(不然会错)
注意如果T是2L的倍数最好补成T=2L类别=0,不然还要讨论0和T的倍数情况
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 a[300001],n,L,i,j,k,l,sum,Sum;
ll ans,X[300001],T[300001];
int main()
{
#ifdef file
freopen("agc022d.in","r",stdin);
#endif
scanf("%d%d",&n,&L);
fo(i,1,n) scanf("%lld",&X[i]);
fo(i,1,n)
{
scanf("%lld",&T[i]);
if (!(T[i]%(L*2)))
ans+=(T[i]/(L*2)-1)*2,T[i]=L*2;
else
ans+=(T[i]/(L*2))*2,T[i]%=L*2;
}
fo(i,1,n) a[i]=((X[i]*2)>=T[i])+2*(((L-X[i])*2)>=T[i]),ans+=(!a[i])*2;
++ans,sum=0;
if (a[n]==2)
{
fo(i,1,n)
if (a[i]==3) ++sum,++Sum;
else
if (a[i]==2)
{
if (i==n) ++ans;
else ans+=2;
if (i<n && sum) --sum,--Sum;
}
}
else
{
fo(i,1,n)
if (a[i]==3) ++sum,++Sum;
else
if (a[i]==2)
{
ans+=2;
if (sum) --sum,--Sum;
}
++ans;
if (!a[n])
{
sum=0;
fd(i,n,1)
if (a[i]==3) ++sum;
else
if (a[i]==1)
{
ans+=2;
if (sum) --sum,--Sum;
}
}
else
{
sum=0;
fd(i,n,1)
if (a[i]==3)
{
if (i==n) --Sum;
else ++sum;
}
else
if (a[i]==1)
{
ans+=2;
if (sum) --sum,--Sum;
}
}
}
ans+=Sum;
ans+=ans&1;
printf("%lld\n",ans*L);
fclose(stdin);
fclose(stdout);
return 0;
}