E. Increasing by Modulo
题意
一个长度为 n n n 的数组a
,每次可以选择一部分 a i a_i ai ,使得 a i = ( a i + 1 ) m o d m a_i = (a_i + 1)\space mod \space m ai=(ai+1) mod m ,求最少需要几次操作使得这个数组单调不减。
题解
- 二分操作次数;
- 每个数都有 m i d mid mid 次操作机会,保证单调递增的同时尽量让当前的数尽可能的小。
代码
#include <bits/stdc++.h>
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
#ifdef LOCAL
#include "Print.h"
#define de(...) W('[', #__VA_ARGS__,"] =", __VA_ARGS__)
#else
#define de(...)
#endif
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 5;
int n, m, a[maxn];
bool judge(int mid) {
int mx = 0;
rep(i, 1, n) {
if (a[i] > mx) {
if (mx + m - a[i] > mid) mx = a[i];
} else {
if (mx - a[i] > mid) return 0;
}
}
return 1;
}
int solve() {
scanf("%d%d", &n, &m);
rep(i, 1, n) scanf("%d", &a[i]);
int l = 0, r = m;
while (l < r) {
int mid = (l + r) >> 1;
if (judge(mid)) r = mid;
else l = mid + 1;
}
printf("%d\n", r);
return 0;
}
int main() {
#ifdef LOCAL
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
#endif
int T = 1;
// scanf("%d", &T);
while (T--) solve();
return 0;
}