C. Increasing by Modulo

Links: https://codeforces.com/contest/1169/problem/C

Meaning of the questions:

Toad Zitz has an array of integers, each integer is between 00 and m1m−1 inclusive. The integers are a1,a2,,ana1,a2,…,an.

In one operation Zitz can choose an integer kk and kk indices i1,i2,,iki1,i2,…,ik such that 1i1<i2<<ikn1≤i1<i2<…<ik≤n. He should then change aijaij to ((aij+1)modm)((aij+1)modm) for each chosen integer ijij. The integer mm is fixed for all operations and indices.

Here xmodyxmody denotes the remainder of the division of xx by yy.

Zitz wants to make his array non-decreasing with the minimum number of such operations. Find this minimum number of operations.

 Ideas:

Dichotomy, given the current number of steps can meet the conditions can be. Analyzing time, if ai + 1 <ai ai is applied to determine whether to make ai + 1, if not the current number of steps is not, if ai + 1> ai. Also as far as possible ai + 1 = ai, if not is not terminated.

Code:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int MAXN = 3e5 + 10;
const int MOD = 1e9 + 7;
int n, m, k, t;
int a[MAXN];

bool Check(int cnt)
{
    int temp = 0;
    for (int i = 1;i <= n;i++)
    {
        if (a[i] < temp)
        {
            int ops = temp-a[i];
            if (ops > cnt)
                return false;
        }
        else if (a[i] > temp)
        {
            int ops = m-a[i]+temp;
            if (ops > cnt)
                temp = a[i];
        }
    }
    return true;
}

int main()
{
    cin >> n >> m;
    for (int i = 1;i <= n;i++)
        cin >> a[i];
    int l = 0, r = m;
    int res = m;
    while (l < r)
    {
        int mid = (l+r)/2;
        if (Check(mid))
        {
            res = min(res, mid);
            r = mid;
        }
        else
            l = mid+1;
    }
    cout << res << endl;

    return 0;
}

  

Guess you like

Origin www.cnblogs.com/YDDDD/p/10930217.html