CF713E

CF713E [* easy]

有一个长度为 \(m\) 的环,最初有 \(n\) 个点上有人。

每秒可以让所有人都走一步(初始选定所有人的方向)

求使得所有点都被走过的最短时间。

\(n\le 10^5,m\le 10^9\)

Solution

我们发现答案的上界是最长的段。

考虑二分答案,然后 check

如果是序列的话,我们可以这样 dp,设 \(f_i\) 表示考虑到第 \(i\) 个点,

如果 \(f_{i-1}<a_i\),那么当前点必须往前走,否则往后走。

然而有一个问题,有可能是 \(i-1\) 帮忙覆盖了,然后 \(i\) 就只需要往前覆盖。

不难发现我们一定没有必要让 \(i-2\) 往后覆盖并以此使得 \(i\) 往前走,因为此时 \(i-1\) 一定可以往后走。

所以分类讨论一下即可。

然后我们发现环非常的不好处理。

但是最长的段一定是会被断开的。

所以枚举一下他两边的点是如何 choose 的,然后断环为链,你就 win 了,要注意如果他往右走,那么他的下一个可以往前走。

复杂度 \(\mathcal O(n\log m)\)

\(Code:\)

#include<bits/stdc++.h>
using namespace std ;
#define Next( i, x ) for( register int i = head[x]; i; i = e[i].next )
#define rep( i, s, t ) for( register int i = (s); i <= (t); ++ i )
#define drep( i, s, t ) for( register int i = (t); i >= (s); -- i )
#define re register
int gi() {
	char cc = getchar() ; int cn = 0, flus = 1 ;
	while( cc < '0' || cc > '9' ) {  if( cc == '-' ) flus = - flus ; cc = getchar() ; }
	while( cc >= '0' && cc <= '9' )  cn = cn * 10 + cc - '0', cc = getchar() ;
	return cn * flus ;
}
const int N = 2e5 + 5 ;  
int n, m, a[N], b[N], dp[N], d, id ; 
bool check(int x) {
	rep( j, 0, 1 ) {
		rep( i, 0, n ) dp[i] = -m ;
		int Ed = m + b[1] - j * x, fs = Ed ; //j = 0 means after
		dp[1] = b[1] + (j ^ 1) * x ;
		if(!j) fs = m + b[2] - x - 1, dp[2] = max( b[2], b[1] + x ) ; 
		rep( i, (2 + (j ^ 1)), n ) {
			if( dp[i - 2] >= b[i] - x - 1 ) dp[i] = b[i - 1] + x ;
			if( dp[i - 1] >= b[i] - x - 1 ) dp[i] = max(dp[i], b[i]) ;
			if( dp[i - 1] >= b[i] - 1 ) dp[i] = b[i] + x ;
		}
		if( dp[n] >= min( Ed - 1, fs ) ) return 1 ;
	} return 0 ; 
}
signed main()
{
	m = gi(), n = gi() ; 
	rep( i, 1, n ) a[i] = gi(), a[i + n] = a[i] + m ;
	if( n == 1 ) { printf("%d\n", m - 1 ) ; exit(0) ; }
	rep( i, 2, n + 1 ) {
		int di = a[i] - a[i - 1] ; 
		if( d < di ) d = di, id = i ; 
	}
	rep( i, 1, n ) b[i] = a[i + id - 1] ; 
	int l = 0, r = d, ans = d ; 
	while( l <= r ) {
		int mid = (l + r) >> 1 ; 
		if(check(mid)) ans = mid, r = mid - 1 ;
		else l = mid + 1 ; 
	}
	printf("%d\n", ans ) ;
	return 0 ;
}
posted @ 2020-10-10 16:00  Soulist  阅读(100)  评论(0编辑  收藏  举报