zoukankan      html  css  js  c++  java
  • [BZOJ5416][LOJ2719][NOI2018]冒泡排序[DP+组合数学]

    (S=frac{1}{2}sum_{i=1}^n|i-p_i|),每次swap最好情况下会让 (S) 减少 (2),所以如果交换次数恰好是 (frac{1}{2}sum_{i=1}^n|i-p_i|),那么每个数都不能向 (p_i) 的反方向移动,也就是排序过程中,某个数字不能同时有往后和往前移动两个操作。

    冒泡排序的过程是顺序比较每个数字和后面的数字,对于每个数字,如果往后移,前面肯定没有比它更大的数,所以这个数不会再往前移;如果往前移(前面有更大的数)同时后面有更小的数,这个数字就一定还会往后移。

    所以一个序列不“好”的条件是存在某个位置 (i) 前面有比它更大的数,后面有比它更小的数,即这个序列中存在长度 (>2) 的下降子序列

    不想写了,看 这篇博客吧(雾)

    int a[MAXN >> 1], n;
    
    inline Mod C(int n, int m) {
      if (m > n) return 0;
      return fac[n] * ifac[n - m] * ifac[m];
    }
    inline Mod Get(int n, int m) {
      return C(n + m - 2, m - 1) - C(n + m - 2, m - 2);//(1,1)走到(n,m)方案数
    }
    
    void init() {
      freopen("inverse.in", "r", stdin);
      freopen("inverse.out", "w", stdout);
      fac[0] = 1;
      lop1(i, MAXN) fac[i] = fac[i - 1] * i;
      ifac[MAXN - 1] = fac[MAXN - 1].inv();
      dlop0(i, MAXN - 1) ifac[i] = ifac[i + 1] * (i + 1);
      assert(ifac[0].a == 1);
    }
    
    void solve() {
      static bitset<600005>vis;
      n = in;
      lop1(i, n) in, a[i];
      int Min = 1, Max = 0;
      vis.reset();
      Mod ans = 0;
      lop1(i, n) {
        while (vis.test(Min)) ++Min;
        int t = n - i + 1, res = n - max(a[i], Max);//可行集合大小
        if (res > 1) ans += Get(t + 1, res);
        else ans += res > 0; //(1, 1)到(n, 1)
        if (Max > a[i] and a[i] > Min) break;//存在长度>2的下降子序列
        chmax(Max, a[i]);
        vis.set(a[i]);
      }
      out, ans.a, '
    ';
    }
    
  • 相关阅读:
    Mybatis Generator 生成的mapper只有insert方法
    someone you loved 歌词翻译
    Illegal instant due to time zone offset transition (Asia/Shanghai)_夏令时问题
    React js ReactDOM.render 语句后面不能加分号
    node js 路由
    node -v node is not define
    怎样从gitHub上面拉项目
    工作3年java面试题整理(自用)
    状态模式
    代理模式
  • 原文地址:https://www.cnblogs.com/storz/p/10422006.html
Copyright © 2011-2022 走看看