首页 > 其他分享 >卡农 -- HNOI2011 -- DP&组合

卡农 -- HNOI2011 -- DP&组合

时间:2024-03-07 09:04:18浏览次数:23  
标签:-- sum nueyong int HNOI2011 ans 卡农 mod

卡农 -- \(HNOI2011\)

$$luogu$$

$$HZOI$$


题意

给定一个 集合 $ A= { 1 \le x \le n | x } $ , 求出其 \(m\) 个不相同的且不为空集的子集,使得第 \(i\) 个元素的在所有选出的子集中出现的次数 \(appear_i \mod 2 = 0\)


题解

首先一个已知结论:

对于一个 \(A\) 这样的集合,他不同的子集个数为 \(2^n\)

那么这时我们减去空集,那么可选的为 \(2^n - 1\) 种。

你影响你最后的每个元素的出现次数的是第 \(m\) 次的选择。

若第 \(i\) 个数在前 \(m - 1\) 个子集中出现的次数为奇数,那么 \(i\) 在最后一个中必定出现。

反之就不会出现。

所以 前 \(m - 1\) 个怎么取值都行。

考虑此时 \(ans_m\) 为 \(m\) 个子集满足条件的方案数。

不考虑什么奇偶,前 \(m - 1\) 个能选的总方案数为 :

\[ans_m += C^{ m - 1 }_{2 ^ n - 1} \]

第一种情况:若 \(1 \dots n\) 在前 \(m - 1\) 个子集中出现的次数均为偶数,则此时末尾为空集,显然不可取,所以:

\[ans_m -= ans_{m - 1} \]

第二种情况:若所有出现次数为奇数的数构成的集合 \(B\) 已经被选入,则:

\[ans_m -= (2 ^ n - 1 - (m - 2)) \times ans_{m - 2} \]

解释一下:

那么我们可以看做就是最后一个集合 \(=\) 第 \(m - 1\) 个集合

那前 \(m - 2\) 个肯定是符合要求的。那肯定前 \(m - 2\) 个是不重叠的那这个重叠的集合的取值种数为 $2 ^ n - 1 - (m - 1) $

最后的处理,现在定义 \(n = 2, m = 3\)

那对于这三种选法,会算成三种,但实际是一种

\[\{1\} , \{2\} , \{1 , 2\} \]

\[\{1\} , \{1 , 2\} , \{2\} \]

\[\{2\} , \{1 , 2\} , \{1\} \]

注意对于前面 $ 2 $ 个集合的来说它的选择的顺序是没关系的。算成三种的原因只是因为最后的一个集合的抠出来的值不同。

所以再除以一个 $ m $

所以 \(DP\) 转移方程为:

\[dp_i = C ^ {i - 1} _ {2 ^ n - 1} - dp_{i - 1} - dp_{i - 2} \times ( 2 ^ n - 1 - ( m - 2 ) ) \]

\(code\)

格式化过的

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std ;
const int N = 1e6 + 1 ;
int dp[ N ], C[ N ] ;
const long long mod = 1e8 + 7 ;
namespace Combination {
int nueyong[ N ], sum_neo[ N ] ;
inline void lear_neoyong() {
    sum_neo[ 0 ] = sum_neo[ 1 ] = 1 ;
    nueyong[ 1 ] = 1 ;
    nueyong[ 0 ] = 1 ;

    // sum[ 0 ] = sum[ 1 ] = 1 ;
    for (int i = 2 ; i < N ; ++ i) {
        int p = mod ;
        int k = p / i ;
        nueyong[ i ] = (k * (p - nueyong[ p % i ])) % p ;
        sum_neo[ i ] = (nueyong[ i ] * sum_neo[ i - 1 ]) % p ;
        // sum[ i ] = ( i * sum[ i - 1 ] ) % p ;
    }
}
int Quick_Pow(int alpha, int beta) {
    int ans = 1 ;

    while (beta > 0) {
        if (beta & 1)
            ans = (ans * alpha) % mod ;

        beta >>= 1 ;
        alpha = (alpha * alpha) % mod ;
    }

    return ans ;
}
} ;
using namespace Combination ;
inline int read() {
    int x = 0, f = 1 ;
    char c = getchar() ;

    while (c < '0' || c > '9') {
        if (c == '-') {
            f = - f ;
        }

        c = getchar() ;
    }

    while (c >= '0' && c <= '9') {
        x = x * 10 + c - '0' ;
        c = getchar() ;
    }

    return x * f ;
}
int n, m, all_time, koul ;
signed main() {
    n = read() ;
    m = read() ;
    lear_neoyong() ;
    all_time = (((Quick_Pow(2, n) - 1) % mod) + mod) % mod ;
    C[ 0 ] = 1 ;
    int tot = all_time ;

    for (int i = 1 ; i <= m ; ++ i) {
        C[ i ] = (C[ i - 1 ] * ((tot + mod) % mod)) % mod ;
        tot -- ;
    }

    dp[ 2 ] = dp[ 1 ] = 0 ;

    for (int i = 3 ; i <= m ; ++ i) {
        int pri = (C[ i - 1 ] * sum_neo[ i - 1 ]) % mod ;
        dp[ i ] = ((((pri - dp[ i - 1 ]) - ((dp[ i - 2 ] * ((all_time - i + 2) % mod + mod) % mod) % mod) + mod) %
                    mod) * nueyong[ i ]) % mod ;
    }

    cout << dp[ m ] ;
}

结尾撒花 \(\color{pink}✿✿ヽ(°▽°)ノ✿\)

标签:--,sum,nueyong,int,HNOI2011,ans,卡农,mod
From: https://www.cnblogs.com/hangry/p/18058072

相关文章

  • CS144_2020_Fall_lab1(流重组)
    废话已经在lab0说完了,我们直接来看lab10一些规定,废话1概述在实验0中,你使用了一个互联网流套接字来从网站获取信息并发送电子邮件,使用了Linux内置的传输控制协议(TCP)实现。这个TCP实现成功地产生了一对可靠的按顺序的字节流(一个从你到服务器的流,另一个在相反的方向),即使底层......
  • 上来就对标 20k Star 的开源项目,是自不量力还是后起之秀?
    先来一段紧箍咒:nvm、fvm、gvm、sdkman、fnm、n、g、rvm、jenv、phpbrew、rustup、swiftenv、pyenv、rbenv...这些都是用来解决编程语言多版本管理的工具,如果你是个程序员肯定认识或是用过几个,但是刚接触编程的小白,就会有些挠头了。啥是编程语言版本管理工具?它们有什么用呢?举个......
  • 僵尸进程和孤儿进程
    (一)引入我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程到底什么时候结束。当一个进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进......
  • Python中判定列表是否包含某个元素的方法
    大家好,我是彭涛,今天为大家分享Python中判定列表是否包含某个元素的方法,全文4000字,阅读大约10分钟。在Python编程中,判定一个列表是否包含特定元素是一项常见任务。本文将深入研究各种方法,从基本的成员运算符到更高级的函数和库的应用,为大家提供全方位的指南和实用示例。1.成......
  • Laravel 中 faker 的方法总结
    Laravel中faker的方法总结428513 liuguowei163的个人博客 /  1878 /  13 / 创建于 4年前 / 更新于4年前 安装composerrequirefzaninotto/faker可通过在 config/app.php 增加如下配置使其支持中文:'faker_locale'=>'zh_CN',基本用法Fake......
  • 企业级应用于架构设计笔记
    课堂笔记-主要是给自己复习的第一节课课程结构:架构定义:用一致认可方式从多个角度对系统的组成部分及各部分之间的协作关系所做的描述。软件架构的定义(软件体系结构SoftwareArchitecture):用开发团一致认可的方式从多个角度(业务、开发、运维等)对软件的组成部分及各部分之间的协......
  • MySQL binlog/redolog/undolog 的区别?
    想和大家聊聊InnoDB中的锁机制,那么不可避免的要涉及到MySQL的日志系统,binlog、redolog、undolog等,看到有小伙伴总结的这三个日志还不错,赶紧拿来和各位小伙伴分享。日志是 mysql 数据库的重要组成部分,记录着数据库运行期间各种状态信息。mysql日志主要包括错误日志、......
  • 宕机后,Redis如何实现快速恢复?
    Redis作为非常火热的内存数据库,其除了具有非常高的性能之外,还需要保证高可用,在故障发生时,尽可能地降低故障带来的影响,Redis也提供了完善的故障恢复机制:哨兵。下面就来具体来看看Redis的故障恢复是如何做的,以及其中的原理。部署模式Redis在部署时,可以采用多种方式部署,每种部署方......
  • EMR 电子病历模版分类树
    EMR 病案首页 病案首页 病案首页(中医) 住院志 入院记录(通用) 入院记录(儿科) 入院记录(妇科) 出院记录(通用) 出院记录(儿科) 出院记录(妇科) 24小时内入出院记录 24小时内入院死亡记录 入院记录(神经内科) 病程记录 首次病程记录 日常病程记录 抢救记录 输血记录 有创诊疗操作......
  • 1277. 维护序列
    #include<iostream>#include<stdio.h>#include<algorithm>#include<string>#defineFor(i,j,n)for(inti=j;i<=n;++i)usingnamespacestd;typedeflonglongLL;constintN=1e5+5;intn,m,P,a[N];structnod......