二分-Codeforces-1169C Increasing by Modulo

题目链接
题意:
n个数,每进行一次操作可以任选其中几个数使其变为+1后对m取余的数
求将这个数列变为非递减序列(后面的数总是大于等于前面的数)的最小操作次数
思路:
这道题想到二分就很简单了。。。(时间复杂度log2(n))
剩下的过程见注释

#include
#include
using namespace std;
int a[300005];
int main()
{
    int n,m,i;
    scanf("%d%d",&n,&m);
    for(i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
    }
    int l=0,r=m,ans;
    while(l<=r)
    {
        int mid;
        int flag=0;
        mid=(l+r)/2;
        int pre=0;//前一个数的取值
        for(i=1; i<=n; i++)
        {
            int vis;
            if(a[i]+mid>=m)
            {
                vis=1;//此时a[i]的取值范围是 [a[i],m-1]∪[0,a[i]+mid-m]
            }
            else
            {
                vis=0;//此时a[i]的取值范围 [a[i],a[i]+mid]
            }
            if(vis==0)
            {
                if(a[i]+mid>=pre)
                {
                    pre=max(a[i],pre);
                    if(i==n)
                        flag=1;
                }
                else
                    break;
            }
            if(vis==1)
            {
                if(a[i]+mid-m>=pre)
                    pre=pre;
                else
                {
                    if(a[i]>=pre)
                        pre=a[i];
                    else
                        pre=pre;
                }
                if(i==n)
                    flag=1;
            }
        }
        if(flag==1)
        {
            r=mid-1;
            ans=mid;
        }
        else
            l=mid+1;
    }
    printf("%d\n",ans);
}

你可能感兴趣的:(Codeforces,二分)