ARC152 简要题解
A. Seat Occupation
B. Pass on Path
两人一定相交两次,不妨设第一次相交在 \(l\),第二次相交在 \(r\),\(l<r\),则从 \(l\) 出发相背而行,再到 \(r\),这个时间差为 \(2|a_l-(L-a_r)|\),则整体答案为 \(2L+2|a_l-(L-a_r)|\)。这也说明了直接从一个点出发相背而行就是正确的。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
const int mod=1e9+7;
#define inf 1e9
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
int n,m,a[maxn],ans=inf;
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++){
int p=lower_bound(a+1,a+1+n,m-a[i])-a-1;
if(p)ans=min(ans,abs(m-a[i]-a[p]));
if(p<n)ans=min(ans,abs(m-a[i]-a[p+1]));
}printf("%lld\n",2ll*(m+ans));
return 0;
}
C. Pivot
考虑到无论如何操作,极差不变,于是设为 \(d\),转化为最小化最小值。
考虑操作极值时,最小值变化总是 \(d\),于是变为最小化最小值 \(\%d\),且无需考虑负数的问题了。
对于一个非极值 \(x\),操作 \(x\) 可以使最小值加 \(2(x-Mn)\),再操作最大值,再操作它又可以得到相同的变化。操作一次极值,则 \(x\) 变为 \(2Mn-x\),则也可以加若干次 \(2(Mn-x)\)。
于是可以最小化到 \(Mn\%\gcd(d,2(x-Mn))+d\),就是这样。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int n,m,a[maxn],g,d;
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
g=d=a[n]-a[1];
for(int i=2;i<=n;i++)
g=__gcd(g,2*(a[i]-a[1]));
printf("%d\n",a[1]%g+d);
return 0;
}