• guruguru


    guruguru

    时间限制: 1 Sec  内存限制: 128 MB

    题目描述

    Snuke is buying a lamp. The light of the lamp can be adjusted to m levels of brightness, represented by integers from 1 through m, by the two buttons on the remote control.
    The first button is a "forward" button. When this button is pressed, the brightness level is increased by 1, except when the brightness level is m, in which case the brightness level becomes 1.
    The second button is a "favorite" button. When this button is pressed, the brightness level becomes the favorite brightness level x, which is set when the lamp is purchased.
    Snuke is thinking of setting the favorite brightness level x so that he can efficiently adjust the brightness. He is planning to change the brightness n−1 times. In the i-th change, the brightness level is changed from ai to ai+1. The initial brightness level is a1. Find the number of times Snuke needs to press the buttons when x is set to minimize this number.

    Constraints
    2≤n,m≤105
    1≤ai≤m
    ai≠ai+1
    n, m and ai are integers.
     

    输入

    Input is given from Standard Input in the following format:
    n m
    a1 a2 … an

    输出

    Print the minimum number of times Snuke needs to press the buttons.

    样例输入

    4 6
    1 5 1 4
    

    样例输出

    5
    

    来源/分类

    ABC066&ARC077 


    题意:有n个数,每次要把a[i-1]变成a[i],有两种操作,给a[i-1]加1或者把a[i-1]变成一个指定的数x,问最小操作次数。

    考虑维护数组sum[i],表示若把指定的数设置为i所减少的操作次数。若是a[i-1]>a[i],就把a[i]加m,这样方便统计。

    设L=a[i-1],R=a[i]。要是x为L+1,减少次数为0,x为L+2,减少次数为1,x为L+3,减少次数为2.。。。。。。

    于是每次就相当于把L+2到R区间里每次加上1到R-(L+2)+1.

    考虑维护二次差分。如果要把区间[L,R]的数依此加上1到(R-L+1),则只需要在L加1,R+1减((R-L+1)+1),R+2加(R-L+1)

    #include<bits/stdc++.h>
    #define N 100050
    using namespace std;
    int a[N];
    long long dis[2*N];
    long long sum=0;
    
    int main()
    {
        int n,m;
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    
        for(int i=2;i<=n;i++)
        {
            int l=a[i-1],r=a[i];
            if(r<l)r+=m;
            sum+=r-l;
    
            if(r-l>1)
            {
                dis[l+2]+=1;
                dis[r+1]-=r-(l+2)+1+1;
                dis[r+2]+=r-(l+2)+1;
            
            }
        }
    
        long long ans=0;
        for(int i=1;i<=2*m;i++)dis[i]+=dis[i-1];
        for(int i=1;i<=2*m;i++)dis[i]+=dis[i-1];
    
        for(int i=1;i<=m;i++)ans=max(ans,dis[i]+dis[i+m]);
    
            printf("%lld",sum-ans);
    
        return 0;
    }
    View Code
  • 相关阅读:
    Manjaro Linux自带的Python没有安装IDLE的解决办法
    Python入门 | IDLE的介绍和使用方法
    用U盘装CentOS 7出现dracut:/#问题的解决办法
    在Ubuntu下,如何安装坚果云deb文件
    windows7下进行ubuntu U盘启动盘的制作
    oracle 死锁和锁等待区别
    MySQL数据库设计总结
    oracle开机自启
    微信备份提示当前网络状况复杂,请尝试使用其他网络的解决方法
    ORA-27090 Unable to reserve kernel resources for asynchronous disk I/O
  • 原文地址:https://www.cnblogs.com/tian-luo/p/9443648.html
Copyright © 2020-2023  润新知