• [题解] CF1392F Omkar and Landslide


    Luogu CF.ML

    结论题。

    首先,最后的位置和操作的顺序没有关系。

    显然最后 (h_{i+1}-h_i in {0, 1})。暴力算一些答案,可以发现最后的差分序列中最多有 (1)(0)

    结论:最后的序列中满足 (h_i = h_{i+1})(i) 数量不超过 (1)

    证明

    考虑从点 (i) 开始向左依次推进的算法:

    • 如果 (i = 1)(h_i - h_{i - 1} < 2),结束;
    • 否则 (h_i leftarrow h_i - 1, ;h_{i-1} leftarrow h_{i-1}+1, ;i leftarrow i-1),回到第一步递归执行。

    执行一次推进后,如果 (i) 左边的数互不相等,那么会一直推进到 (1),这可能使相等对数增加 (1),否则,若 (h_i = h_{i + 1}),那么推进操作会在 (i+1) 处结束,使相等对数减少 (1) 或不变(高度形如 (x, x, x+2) 等时个数不变)。

    那么依次对 (2, 3, dots, n) 执行推进,就容易发现相等对始终不会超过 (1) 对。

    有了这个结论,可以发现 (S = sum h_i) 唯一确定了一个最终的高度序列。先假设没有相等对,那么 (displaystyle sum h_i = S = frac{n(2h_1 + n - 1)}{2}),解出 (h_1)(上取整),再调整其中一个不会增加的位置即可。

    参考实现:

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define File(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
    typedef long long ll;
    namespace io {
      const int SIZE = (1 << 21) + 1;
      char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
      #define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
      char getc () {return gc();}
      inline void flush () {fwrite (obuf, 1, oS - obuf, stdout); oS = obuf;}
      inline void putc (char x) {*oS ++ = x; if (oS == oT) flush ();}
      template <class I> inline void gi (I &x) {for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;}
      template <class I> inline void print (I x) {if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;while (x) qu[++ qr] = x % 10 + '0',  x /= 10;while (qr) putc (qu[qr --]);}
      struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
    }
    using io :: gi; using io :: putc; using io :: print; using io :: getc;
    template<class T> void upmax(T &x, T y){x = x>y ? x : y;}
    template<class T> void upmin(T &x, T y){x = x<y ? x : y;}
    
    const int N = 1000005;
    
    int main(){
      // File("f");
      ll s = 0, n = 0;
      gi(n);
      for(int i=1; i<=n; i++){
        ll x;
        gi(x);
        s += x;
      }
      ll p = (2 * s - n * (n - 1) - 1) / (n * 2) + 1;
      ll ns = (2 * p + n - 1) * n / 2;
      ll pos = n - (ns - s);
      for(int i=1; i<=pos; i++) print(p + i - 1), putc(' ');
      for(int i=pos+1; i<=n; i++) print(p + i - 2), putc(' ');
      putc('
    ');
      return 0;
    }
    
  • 相关阅读:
    ubuntu开启SSH服务
    Ubuntu修改虚拟内存(即swap空间)
    【转】Ubuntu 13.10中MyEclipse 10.6+下载+安装+破解
    【转】 ubuntu下安装mysql
    【转】 Ubuntu 11.04 下安装配置 JDK 7
    Linux非root用户安装jdk和tomcat
    algorithm之改变序列算法--待解决
    时间日期设置--ctime头文件
    C中的一些函数
    algorithm之不变序列操作
  • 原文地址:https://www.cnblogs.com/RiverHamster/p/sol-cf1392f.html
Copyright © 2020-2023  润新知