E. Increasing by Modulo

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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43860866/article/details/118389767