D、Homework of PE 容斥原理

终于想懂了这个容斥,

华工4月23号校赛,
考虑总的所有情况,设1---n里面含有质数的个数为all,需要固定m个质数。那么有

totSum = C(all, m) * (n - m)!,就是在all个质数里面,任意选m个出来固定,剩下的全排。

但是算多了,因为还有一些质数(不在那m个之内)也会被固定,

而且,考虑样例

5 1,

1 2 3 4 5


这个时候,先考虑任选m个出来固定,题目就是任选1个出来固定。剩下的全排

比如固定了2,剩下的全排,会产生,只固定了2,固定了2、3,固定了2、5,固定了2、3、5

比如固定了3,剩下的全排,会产生,只固定了3,固定了2、3,固定了3、5,固定了2、3、5

比如固定了5,剩下的全排,会产生,只固定了5,固定了2、5,固定了3、5,固定了2、3、5

那么只有第一列相加的才是正确答案。后面的要减去。

减去固定了两个的时候,

这个时候前面一个已经固定了,再枚举一个来固定,就是固定2个。所以固定(3, 2)和(2, 3)是不同的方案。

固定了(2, 3)时,会有,只固定2、3和固定了2、3、5

固定了(3, 2)时,会有,只固定3、2和固定了3、2、5

.....

等等。

减去这些后,会发现结果是ans - 3 * (固定了2、3、5),加回来就是了。

就是一个容斥,以后容斥要实打实写出来,毕竟不是大神。

哭~~~~

比赛没想到。刚才也想了很久,光想是不行的。要模拟。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>

bool check(int val) {
    int en = (int)sqrt(val);
    for (int i = 2; i <= en; ++i) {
        if (val % i == 0) return false;
    }
    return true;
}
const int MOD = 1e9 + 7;
LL fac[222];
LL quick_pow(LL a, LL b, LL MOD) {  //求解 ab % MOD的值
    LL base = a % MOD;
    LL ans = 1; //相乘,所以这里是1
    while (b) {
        if (b & 1) { //用quick_mul防止Miller_Rabin那里溢出。
            ans = ans * base % MOD;
//            ans = quick_mul(ans, base, MOD); //如果这里是很大的数据,就要用quick_mul
        }
        base = base * base % MOD;
//        base = quick_mul(base, base, MOD);    //notice。每次的base是自己base倍
        b >>= 1;
    }
    return ans;
}

LL C(LL n, LL m, LL MOD) {
    if (n < m) return 0; //防止sb地在循环,在lucas的时候
    if (n == m) return 1 % MOD;
    LL ans1 = 1;
    LL ans2 = 1;
    LL mx = max(n - m, m); //这个也是必要的。能约就约最大的那个
    LL mi = n - mx;
    for (int i = 1; i <= mi; ++i) {
        ans1 = ans1 * (mx + i) %MOD;
        ans2 = ans2 * i % MOD;
    }
    return (ans1 * quick_pow(ans2, MOD - 2, MOD) % MOD); //这里放到最后进行,不然会很慢
}
int n, m;
void work() {
    fac[0] = 1;
    for (int i = 1; i <= 200; ++i) {
        fac[i] = fac[i - 1] * i % MOD;
    }
    int all = 0;
    for (int i = 2; i <= n; ++i) {
        all += check(i);
    }
    LL ans = C(all, m, MOD) * fac[n - m] % MOD;
//    cout << ans << endl;
    for (int i = 1; i <= all - m; ++i) {
        if (i & 1) {
            ans = (ans + MOD - C(all, m, MOD) * C(all - m, i, MOD) * fac[n - (m + i)] % MOD) % MOD;
        } else ans = (ans + C(all, m, MOD) * C(all - m, i, MOD) * fac[n - (m + i)] % MOD) % MOD;
    }
    cout << ans % MOD << endl;
}

int main() {
    freopen("data.txt", "r", stdin);
freopen("DataMy.txt", "w", stdout);
    while (~scanf("%d%d", &n, &m))
        work();
    return 0;
}

时间: 2024-10-07 14:39:27

D、Homework of PE 容斥原理的相关文章

hdu 4790 Just Random 容斥原理+数学

Just Random Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1723    Accepted Submission(s): 483 Problem Description Coach Pang and Uncle Yang both love numbers. Every morning they play a game w

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f

BZOJ3198 SDOI2013 spring HASH+容斥原理

题意:给定6个长度为n的数列,求有多少个数对(i,j)((i,j)≡(j,i))使得i和j位置恰好有K个数相同,其中0≤K≤6 题解: 设fi=至少有K个数相同的位置对的数量,用2^6枚举每一种可能,根据容斥原理,答案就是\[\sum\limits_{i = K}^N {{f_i}C_i^K{{\left( { - 1} \right)}^{i - K}}} \] 至于多乘一个组合数,是因为当前枚举到有x个数相同,一个位置对有i个相同的数,那么累计的时候就会算成$C_x^i$,因此实际上这个位置

CFT 1.3 PE IBM 服务器系统专用的PE工具

分享一个IBM 服务器专用的PE工具,此工具方便简洁,可用于IBM 企业级服务器系统备份还原. 有了CFT 1.3 PE  再也不愁服务器系统崩溃了..哈哈 简介: 1.CFT 是一个基于win7内核的WinPE : 2.CFT 已经添加了很多IBM的阵列卡驱动,所以直接启动就能认到很多服务器的硬盘: 3.如果木有认到你的服务器的硬盘,你可以: a.准备服务器阵列卡的win2008 32位驱动. b.在设备管理器里手工更新阵列卡驱动,或者试试桌面的工具:给PE加驱动1和给PE加驱动2. 4.忘了

HDU 1789 Doing Homework again(贪心)

Doing Homework again Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadlin

PE文件结构与函数导出表——详解与实例

PE文件结构与函数导出表--详解与实例 随着windows系统从Xp升级到Win7.Win8, 从32位升级到64位,PE文件结构在整体未变的情况下发生了一些小的变动,一方面是推荐的程序装载地址未采用,另一方面,导出函数序号不再是简单的升序,而是一定程度上的进行了乱序.本文首先对PE文件结构进行了详尽的解说,接着介绍了如何得出函数导出表,整个过程采用SysWoW64目录下的wininet.dll实例进行说明.在介绍过程中,明确指出了Win7.Win8等新系统相对Xp带来的区别. 文章链接:htt

uva 1489 - Math teacher&#39;s homework(数位dp)

题目链接:uva 1489 - Math teacher's homework 题目大意:给定n,k,以及序列m1,m2,-,mn, 要求找到一个长度为n的序列,满足0<=xi<=mi, 并且x1XORx2XOR-XORxn=k 解题思路:数位dp,在网上看了别人的代码,高大上... 假设有二进制数 k : 00001xxxx mi:0001xxxxx, 那么对于xi即可以满足任意的x1XORx2XOR-XORxi?1XORxi+1XOR-XORxn,根据这一点进行数位dp. dp[i][j]

PE文件基础

① PE (Portable Executable):微软参考COFF(Common Object File Format)规范,在Windows NT系统上制定的一种标准, 用于exe可执行文件.obj目标文件和dll动态链接库等文件格式.PE32+是PE的64位扩展,其并未添加额外结构,只是把原来32位的字段变成了64位. 与COFF一样,PE也是基于段(Segment,注:有时也被叫节Section)的结构, 按照不同属性将信息分段存放,常见的段有:代码段(.text).数据段(.data

[BZOJ 1042] 硬币购物 容斥原理

题意 有四种货币, 它们的价值分别是 c[0], c[1], c[2], c[3] . n 次询问, 每次给定 d[0], d[1], d[2], d[3], s, 问凑出 s , 且第 i 种货币不超过 c[i] 个的方案数. c[i], d[i], s <= 100000 , n <= 1000 . 分析 设第 i 种货币取了 x[i] 个. 问题转化为求不定方程 c[0]x[0] + c[1]x[1] + c[2]x[2] + c[3]x[3] = s 的非负整数解的个数. 且满足 4