zoukankan      html  css  js  c++  java
  • 【GDOI2018】D1T2 密码锁(lock)

    题目大意

      给出n个数,每次选择任意一个区间加或减1,求最少多少次能在$mod m$意义下全变成0。

    Solution

      首先我们对于这n个数前后加个零,在$mod m$意义下差分一下。

      $f[i]=(a[i]-a[i-1]+m)mod m$

      于是区间加减1操作就转换成了在某一位加一,另一位减一。

      容易发现,每个数只会加到m或者减到1,而不会有多次循环。

      这样我们对差分序列排个序,在前半部分选择$l$减到1,后半部分选择$r$个加到n,($l+r=n$)

      这题就没了。

    AC Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cctype>
    using namespace std;
    #define MAXBUF 50000000
    char buffer[MAXBUF];
    int pos;
    inline void load(){
        fread(buffer,1,MAXBUF,stdin);
        pos=0;
    }
    inline char gchar(){
        return buffer[pos++];
    }
    inline int rd(){
        int ret=0,f=1;char c=gchar();
        for(;!isdigit(c);)
            if(c=='-')f=-1,c=gchar();else c=gchar();
        for(;isdigit(c);)ret=ret*10+c-'0',c=gchar();
        return ret*f;
    
    }
    int n,m,nl,nr;
    int f[500010],a[500010];
    int main(){
        freopen("lock.in","r",stdin);
        load();
        n=rd();m=rd();
        for(int i=1;i<=n+1;i++)
            a[i]=rd(),
            f[i]=(a[i]-a[i-1]+m)%m;
        sort(f+1,f+n+2);
        for(int l=0,r=n+1;l<=r;)
            if(nl<=nr)
                nl+=f[l++];
            else nr+=m-f[r--];
        printf("%d
    ",nl);
        return 0;
    }
  • 相关阅读:
    [001]
    SpringBoot默认首页跳转设置
    Tomcat网站根目录设置
    SpringBoot获取前端传递JSON的几种方法
    MySQL调优性能监控之show profile
    MySQL新特性MTS
    Java线程池拒绝策略
    快速排序与荷兰国旗及Partition问题
    数据结构与算法之返回最小和问题
    MySQL之谓词下推
  • 原文地址:https://www.cnblogs.com/skylynf/p/8984782.html
Copyright © 2011-2022 走看看