zoukankan      html  css  js  c++  java
  • [清华集训2016] 你的生命已如风中残烛

    简化题意

    (w_i) 全部减 (1),则问题变成一个序列,其中给定有 (n) 个正数 (w_i),其余都是 (-1),和是 (0),前缀和均非负,求排列方案数。

    做法

    如果和是 (1),且要求前缀和全为正数,有结论:每个排列的所有循环移位只有 (1) 种合法,所以计数圆排列数即可,《具体数学》7.5 章有详细证明,其实就是每次必须要取最后一个最小值位置作为起点,使得其他最小值位置跨过序列结尾,前缀和为 (1),否则如果有两个相等最小值而取前一个作为起点,第二个最小值位置前缀和是 (0)

    本题前缀和可以为 (0),因此每个最小值都能取,分析失效。

    证 Catalan 数时,可以在开头放个 (1),但本题中有多种不等价的正数,这种做法是无效的。

    在结尾放个 (-1),问题变成前 (m) 个元素前缀和非负,且总和为 (-1)

    类似地,所有循环移位中现在只能取第一个最小值位置作为起点了,否则跨过序列结尾,之前的最小值位置前缀和会变成 (-1)

    (m+1) 个点共有 (m!) 种圆排列,而序列中有 (m - n + 1)等价(-1) 只能取额外放置的 (1) 个放在结尾(结尾一定是 (-1)),因此答案 (displaystylefrac{m!}{m - n + 1})

    P.S. 对于第一个结论,如果和为 (s),那么有 (s) 种循环移位。

    #include <cstdio>
    
    int main() {
      int n, m = 0, s = 1, x;
      scanf("%d", &n);
      for (int i = 1; i <= n; ++i) {
        scanf("%d", &x);
        m += x;
      }
      for (int i = 2, li = m - n; i <= li; ++i)
        s = 1LL * s * i % 998244353;
      for (int i = m - n + 2; i <= m; ++i)
        s = 1LL * s * i % 998244353;
      printf("%d
    ", s);
      return 0;
    }
    
  • 相关阅读:
    js之自定义鼠标右键菜单
    js之键盘控制div移动
    js之select标签---省市联动小例子
    html之浮动和定位
    java开发简单的用户管理系统
    ASP.NET Web API 2中的属性路由(Attribute Routing)
    ASP.NET Web API中的路由
    Web API 2中的操作结果
    WebApi~通过HttpClient来调用Web Api接口
    Quartz.NET 作业调度
  • 原文地址:https://www.cnblogs.com/RiverHamster/p/sol-lg6672.html
Copyright © 2011-2022 走看看