codechef Count Relations(组合数 二项式定理)

题意

求有多少元素属于$1 \sim N$的集合满足

R1 = {(x,y):x和y属于B,x不是y的子集,y不是x的子集,x和y的交集等于空集}

R2 = {(x,y):x和y属于B,x不是y的子集,y不是x的子集,x和y的交集不等于空集}

Sol

神仙题啊Orz

我整整推了两个小时才推出来

首先写暴力

/*
*/
#include<iostream>
#include<cstdio>
#include<cstring>
//#define int long long
#define LL int
const int MAXN = 1001;
using namespace std;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < ‘0‘ || c > ‘9‘) {if(c == ‘-‘) f = -1; c = getchar();}
    while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = getchar();
    return x * f;
}
int N;
int C[MAXN][MAXN], Po2[MAXN];
main() {
    cin >> N;
    Po2[0] = 1;
    for(int i = 1; i <= 1000; i++) Po2[i] = 2 * Po2[i - 1];
    C[0][0] = 1;
    for(int i = 1; i <= 1000; i++) {
        C[i][0] = 1;
        for(int j = 1; j <= i; j++)
            C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
    }
    int ans = 0;
    for(int i = 1; i <= N - 1; i++) {
        int now = C[N][i], sum = 0;
        for(int j = 1; j <= N - i; j++)    sum += C[N - i][j];
        //ans += now * sum;
        ans += now * (Po2[N - i] - 1);
    }
    cout << ans / 2 << " ";
    ans = 0;
    for(int i = 2; i <= N - 1; i++) {
        int res1 = C[N][i], sum1 = 0;
        for(int j = 1; j <= i - 1; j++) {
            int res2 = C[i][j], sum2 = 0;
            for(int k = 1; k <= N - i; k++) {
                sum2 += C[N - i][k];
            }
            sum1 += res2 * sum2;
        }
        ans += res1 * sum1;
    }
    cout << ans / 2;
    return 0;
}
/*
100 50 10000006
*/

暴力

然后一层一层展开即可

最后的答案为

第一问:

$$\frac{3^n + 1}{2} - 2^n$$‘

第二问:

$$\frac{-3 * 3^n + 4^n - 1}{2} + 3 * 2^{n - 1}$$

/*
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define int long long
#define LL int
const int MAXN = 1001, mod = 100000007, inv = 50000004;
using namespace std;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < ‘0‘ || c > ‘9‘) {if(c == ‘-‘) f = -1; c = getchar();}
    while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = getchar();
    return x * f;
}
int N;
int C[MAXN][MAXN], Po2[MAXN], Po3[MAXN], Po4[MAXN];
int f(int a, int p) {
    int base = 1;
    while(p) {
        if(p & 1) base = (base * a) % mod;
        a = (a * a) % mod; p >>= 1;
    }
    return base % mod;
}
main() {
    int T;
    cin >> T;
    while(T--) {
        cin >> N;
        /*Po2[0] = Po3[0] = Po4[0] = 1;
        for(int i = 1; i <= 1000; i++) Po2[i] = 2 * Po2[i - 1], Po3[i] = 3 * Po3[i - 1], Po4[i] = 4 * Po4[i - 1];
        int ans = (Po3[N] + 1) / 2 - Po2[N];
        cout << ans << " ";
        ans = 0;
        ans = (-3 * Po3[N] + Po4[N] - 1) / 2;
        ans += Po2[N - 1] * 3;
        cout << ans;    */
        //cout << f(2, mod - 2) % mod;
        int ans = ((f(3, N) + 1) * inv - f(2, N) + mod) % mod;
        cout << ans << " ";
        ans = ((-3 * f(3, N) + mod) % mod + f(4, N) - 1 + mod) * inv + f(2, N - 1) * 3 % mod;
        ans %= mod;
        cout << ans << endl;
    }

    return 0;
}
/*
*/

原文地址:https://www.cnblogs.com/zwfymqz/p/9599352.html

时间: 2024-10-09 23:17:46

codechef Count Relations(组合数 二项式定理)的相关文章

容斥原理

对容斥原理的描述 容斥原理是一种重要的组合数学方法,可以让你求解任意大小的集合,或者计算复合事件的概率. 描述 容斥原理可以描述如下: 要计算几个集合并集的大小,我们要先将所有单个集合的大小计算出来,然后减去所有两个集合相交的部分,再加回所有三个集合相交的部分,再减去所有四个集合相交的部分,依此类推,一直计算到所有集合相交的部分. 关于集合的原理公式 上述描述的公式形式可以表示如下:                  它可以写得更简洁一些,我们将B作为所有Ai的集合,那么容斥原理就变成了: 这个

【转载】【容斥原理】

转载自 http://www.cppblog.com/vici/archive/2011/09/05/155103.html 容斥原理(翻译) 前言: 这篇文章发表于http://e-maxx.ru/algo/inclusion_exclusion_principle,原文是俄语的.由于文章确实很实用,而且鉴于国内俄文资料翻译的匮乏,我下决心将其翻译之.由于俄语对我来说如同乱码,而用Google直接翻译中文的话又变得面目全非,所以只能先用Google翻译成英语,再反复读,慢慢理解英语的意思,实在

容斥原理 (转载)

前言: 这篇文章发表于http://e-maxx.ru/algo/inclusion_exclusion_principle,原文是俄语的.由于文章确实很实用,而且鉴于国内俄文资料翻译的匮乏,我下决心将其翻译之.由于俄语对我来说如同乱码,而用Google直接翻译中文的话又变得面目全非,所以只能先用Google翻译成英语,再反复读,慢慢理解英语的意思,实在是弄得我头昏脑胀.因此在理解文章意思然后翻译成中文的时候,中文都不知道如何表述了.而又由于我对容斥原理知识的匮乏,很可能有些地方我的表述是错误的

The Inclusion-Exclusion Principle

The Inclusion-Exclusion Principle The inclusion-exclusion principle is an important combinatorial way to compute the size of a set or the probability of complex events. It relates the sizes of individual sets with their union. Statement The verbal fo

信息学竞赛知识点一览

C++语言 基础算法 位运算 快速幂 模拟 枚举 递推 递归 分治 二分 三分 排序 归并排序 离散化 倍增 贪心 高精度 数据结构 前缀和 差分 栈 对顶栈 单调栈 队列 双端队列 循环队列 单调队列 ST表 链表 链式前向星 Hash表 二叉堆 Huffman树 并查集 路径压缩 按秩合并 扩展域 边带权 树状数组 线段树 延迟标记 扫描线 动态开点线段树 分块 莫队 点分治 BST 平衡树 Treap Splay 红黑树 AVL SBT 替罪羊树 LCT CDQ分治 三维偏序 整体二分 可

nodejs api 中文文档

文档首页 英文版文档 本作品采用知识共享署名-非商业性使用 3.0 未本地化版本许可协议进行许可. Node.js v0.10.18 手册 & 文档 索引 | 在单一页面中浏览 | JSON格式 目录 关于本文档 稳定度 JSON 输出 概述 全局对象 global process console 类: Buffer require() require.resolve() require.cache require.extensions __filename __dirname module e

CodeChef CSUB Count Substrings

Count Substrings Problem code: CSUB Submit All Submissions All submissions for this problem are available. Read problems statements in Mandarin Chinese and Russian. Given a string S consisting of only 1s and 0s, find the number of substrings which st

HDU 4372 Count the Buildings(组合数+斯特林数)

 题意:N座高楼,高度均不同且为1-N中的数,从前向后看能看到F个,从后向前看能看到B个,问有多少种可能的排列数. 思路:一开始想的是dp,但是数据范围达到2000,空间复杂度无法承受. 考虑以最高的楼分界,左边有f-1个递增的楼,右边有b-1个递减的楼,考虑将剩下n-1楼分为f+b-2组,规定每组中最高的在最左边,那么只需要 再从n-1组选出f-1组放到左边即可. 现在解决将n-1个楼分为f+b-2组每组最高的楼在左边的这个问题,这等价于将n-1个楼分为f+b-2个环的排列数,因为长度为n

[组合数取模-逆元计算模板] zoj 3624 Count Path Pair

思路: 正难则反 //C(M+N,M)*C(Q+M-P,Q)-C(N+M-P,N)*C(M+Q,M); 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"stack" #include"algorithm" #include"iostream" using