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;
}
posted @ 2022-11-21 16:32  syzf2222  阅读(137)  评论(0编辑  收藏  举报