码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【ACWing】230. 排列计数


    题目地址:

    https://www.acwing.com/problem/content/description/232/

    求有多少种长度为 n n n的序列 A A A,满足以下条件: 1 ∼ n 1∼n 1∼n这 n n n个数在序列中各出现了一次。若第 i i i个数 A [ i ] A[i] A[i]的值为 i i i,则称 i i i是稳定的,序列恰好有 m m m个数是稳定的。由于满足条件的序列可能很多,所以请你将序列数对 1 0 9 + 7 10^9+7 109+7取模后输出。

    输入格式:
    第一行一个数 T T T,表示有 T T T组数据。
    接下来 T T T行,每行两个整数 n n n、 m m m。

    输出格式:
    输出 T T T行,每行一个整数,表示求出的序列数对 1 0 9 + 7 10^9+7 109+7取模后的值。

    数据范围:
    T ≤ 500000 , n ≤ 1000000 , m ≤ 1000000 T≤500000,n≤1000000,m≤1000000 T≤500000,n≤1000000,m≤1000000

    首先, k k k个数的错排问题的解 f [ k ] f[k] f[k]满足 f [ k ] = ( k − 1 ) ( f [ k − 1 ] + f [ k − 2 ] ) , f [ 1 ] = 0 , f [ 2 ] = 1 f[k]=(k-1)(f[k-1]+f[k-2]),f[1]=0,f[2]=1 f[k]=(k−1)(f[k−1]+f[k−2]),f[1]=0,f[2]=1。参考https://blog.csdn.net/qq_46105170/article/details/125235949。那么本题可以分步骤,先取 m m m个数,方案为 ( n m ) n\choose m (mn​)个,剩下的 n − m n-m n−m个数做错排即可。所以答案就是 ( n m ) f [ n − m ] {n\choose m} f[n-m] (mn​)f[n−m] f f f值可以打个表,阶乘的值也可以打个表。由于 ( n m ) = n ! m ! ( n − m ) ! {n\choose m}=\frac{n!}{m!(n-m)!} (mn​)=m!(n−m)!n!​,而 p = 1 0 9 + 7 p=10^9+7 p=109+7是个素数,从而 a a a模 p p p的逆元可以用费马小定理和快速幂来做。费马小定理为,若 p p p为素数, ( a , p ) = 1 (a,p)=1 (a,p)=1,则 a p − 1 ≡ a a p − 2 ≡ 1 ( m o d    p ) a^{p-1}\equiv aa^{p-2}\equiv1(\mod p) ap−1≡aap−2≡1(modp),从而 a a a的逆元为 a p − 2 a^{p-2} ap−2。逆元可以用记忆化避免重复计算。代码如下:

    #include 
    #include 
    using namespace std;
    
    const int N = 1e6 + 10, P = 1e9 + 7;
    long fac[N], f[N], inv[N];
    int n, m;
    
    long fast_pow(long x, int p) {
      long res = 1;
      while (p) {
        if (p & 1) res = res * x % P;
        x = x * x % P;
        p >>= 1;
      }
      return res;
    }
    
    long inverse(int i) {
      if (~inv[i]) return inv[i];
      return inv[i] = fast_pow(fac[i], P - 2);
    }
    
    long comb(int n, int m) {
      return fac[n] * inverse(m) % P * inverse(n - m) % P;
    }
    
    int main() {
      memset(inv, -1, sizeof inv);
      f[0] = 1, f[1] = 0;
      fac[0] = fac[1] = 1;
      for (int i = 2; i < N; i++) {
        f[i] = (i - 1) * (f[i - 1] + f[i - 2]) % P;
        fac[i] = fac[i - 1] * i % P;
      }
    
      int T;
      scanf("%d", &T);
      while (T--) {
        scanf("%d%d", &n, &m);
        printf("%ld\n", comb(n, m) * f[n - m] % P);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    预处理时间复杂度 O ( N ) O(N) O(N)( N N N为 n n n数据范围),每次询问时间 O ( log ⁡ P ) O(\log P) O(logP), P = 1 0 9 + 7 P=10^9+7 P=109+7。

  • 相关阅读:
    从零开始,无需公网IP,搭建本地电脑上的个人博客网站并发布到公网
    【WSN定位】基于chan算法实现无源定位附matlab代码
    如何让一个uniform variable在多级shader中都起作用(类似C语言的全局变量)?
    多模态大模型训练数据集汇总介绍
    Python数据可视化案例
    认识一些分布函数-Frechet分布及其应用
    1.7.1、常见的计算机网络体系结构
    贝壳找房上海研发全员被优化,公司回应来了!
    8秒完成2万个基因的生存分析 运行速度太慢怎么办 批量单基因生存回归 tcga geo数据分析策略
    创建第一个Spring项目并使用
  • 原文地址:https://blog.csdn.net/qq_46105170/article/details/126093274
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号