code forcesA. Increasing by Modulo

给个数组a和模数m,进行n次操作让这个数组变为不降序列,每次操作可以选择数组中顺序的k个a[i],并将其替换为(a[i]+1)%m。
思路:首先进行的操作不超过m次,如果用了m次,那么(a[i]+m)%m还是a[i],没用,因此从0到m进行二分查找次数,对于每个次数检验能否让该序列不降。

#include <bits/stdc++.h>
#include <vector>
using namespace std;
const int SIZE=3e5+5;
int n,M,ans;
vector<int>a;

void Input()
{
    cin>>n>>M;
    a.push_back(0);
    for(int i=1,tmp;i<=n;i++)
    {
        cin>>tmp;
        a.push_back(tmp);
    }
}

void Binary()
{
    int l=0,r=M,flag,mid;
    while(l<=r)
    {
        flag=1;
        mid=(l+r)/2;
        for(int i=1,pre=0;i<=n;i++) //pre保存要检查的数的前面一个,因为二分有个while循环,所以不直接用a[i-1]
        {
            if(a[i]+mid<M)    //如果经过mid次操作后这个数没有超过模数M,因为操作可以少于mid所以操作后得到的数是个范围,此时为a[i]~a[i]+mid
            {
                if(pre<=a[i]+mid)  
                {
                    if(pre<a[i])   //因为不降且操作数最小 pre>=a[i]时,把a[i]变成pre,则对于a[i+1],pre不变,pre<a[i]时,pre更新为a[i]
                        pre=a[i];
                    continue;
                }
                else       //由于得到的范围最大为a[i]+mid,如果前面的数大于a[i]+mid,那么就不能通过mid次达到目的,标志置0
                {
                    flag=0;
                    break;
                }
            }
            else
            {
                if(pre<a[i]&&pre>a[i]+mid-M)  //道理同上
                    pre=a[i];
            }
        }
        if(flag)
        {
            ans=mid;
            r=mid-1;
        }
        else
            l=mid+1;
    }
}
void Output()
{
    cout<<ans<<endl;
}
int main()
{
    Input();
    Binary();
    Output();
    return 0;
}

参考会飞的鱼的博客

发布了33 篇原创文章 · 获赞 14 · 访问量 449

猜你喜欢

转载自blog.csdn.net/qq_44077455/article/details/93178416