zoukankan      html  css  js  c++  java
  • CF-Educational Codeforces Round 83-D-Count the Arrays

    题目传送门

    sol:首先我们考虑在一个长度为$n$的序列里只有一个数出现了两次其他数都只出现了一次,那么在序列中出现过的数就有$n - 1$个。而这些数的范围是$[1, m]$,从$[1, m]$里选$n - 1$个不同的数的方案数为$C_{m}^{n - 1}$。这$n - 1$个数里最大的数不能作为出现两次的数,否则就没有峰值了,所以可以作为出现两次的数有$n - 2$个。再考虑这些数的排列,出现两次的数肯定要一个在峰值左边一个在峰值右边,除了出现两次的数和峰值以外还剩$n - 3$个数,这些数可以在峰值左边也可以在峰值右边,所以有$2^{n - 3}$种情况。最终的结果就是$C_{m}^{n - 1}*(n - 2)*(2^{n - 3})$。另外在特判一下$n$是2的情况,如果$n$是2又出现了一对重复的数是没有峰值的,所以结果一定是$0$。

    • 排列组合
      #include <bits/stdc++.h>
      using namespace std;
      typedef long long LL;
      typedef pair<int, int> PII;
      const int MOD = 998244353;
      int quick_pow(int n, int k) {
          int res = 1;
          while (k) {
              if (k & 1) res = 1LL * res * n % MOD;
              n = 1LL * n * n % MOD;
              k >>= 1;
          }
          return res % MOD;
      }
      int main() {
          int n, m;
          scanf("%d%d", &n, &m);
          if (n == 2) return puts("0") * 0;
          int ans = 1LL * (n - 2) * quick_pow(2, n - 3) % MOD;
          int tmp1 = 1, tmp2 = 1;
          for (int i = 1; i <= n - 1; i++) {
              tmp1 = 1LL * tmp1 * (m - i + 1) % MOD;
              tmp2 = 1LL * tmp2 * i % MOD;
          }
          ans = 1LL * ans * tmp1 % MOD;
          ans = 1LL * ans * quick_pow(tmp2, MOD - 2) % MOD;
          printf("%d
      ", ans);
          return 0;
      }
  • 相关阅读:
    js中eval详解
    javascript数组操作大全
    JavaScript面向对象编程深入分析
    IBatisNet系列二QuickStart篇
    IBatis.Net系列Mapped Statements的语法
    MonoRail学习-入门实例篇
    IBatisNet系列执行存储过程
    IBatis.Net系列多参数的SQL语句的配置
    Castle Startable Facility 简单理解
    wxPython创建系统托盘
  • 原文地址:https://www.cnblogs.com/Angel-Demon/p/12455059.html
Copyright © 2011-2022 走看看